Confusione relativa a sigwait nel sistema multiprocesso

2

Ho difficoltà a comprendere l'IPC nel sistema multiprocesso. Ho questo sistema in cui ci sono tre processi figlio che inviano due tipi di segnali al loro gruppo di processi. Esistono quattro tipi di processi di gestione dei segnali responsabili di un particolare tipo di segnale.

C'è questo processo di monitoraggio che attende entrambi i segnali e quindi procede di conseguenza. Quando eseguo questo programma per un po ', il processo di monitoraggio sembra non accorgersi del segnale e del processo di gestione del segnale. Ho potuto vedere nel registro che il segnale viene generato solo ma non gestito affatto.

Il mio codice è riportato di seguito

#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

using namespace std;

double timestamp() {
  struct timeval tp;
  gettimeofday(&tp, NULL);
  return (double)tp.tv_sec + tp.tv_usec / 1000000.;
}

double getinterval() { 
  srand(time(NULL));
  int r = rand()%10 + 1;
  double s = (double)r/100;
}

int count;
int count_1;
int count_2;
double time_1[10];
double time_2[10];


pid_t senders[1];
pid_t handlers[4];
pid_t reporter;

void catcher(int sig) {
  printf("Signal catcher called for %d",sig);
}

int main(int argc, char *argv[]) {

  void signal_catcher_int(int);

  pid_t pid,w;
  int status;

  if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
    perror("1");
    return 1;
  }

  if(signal(SIGUSR2 ,SIG_IGN) == SIG_ERR) {
    perror("2");
    return 2;
  }

  if(signal(SIGINT,signal_catcher_int) == SIG_ERR) {
    perror("3");
    return 2;
  }

  //Registering the signal handler
  for(int i=0; i<4; i++) {
    if((pid = fork()) == 0) {
      cout << i << endl;
      //struct sigaction sigact;
      sigset_t sigset;
      int sig;
      int result = 0;

      sigemptyset(&sigset);

      if(i%2 == 0) {

        if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
          perror("2");
          return 2;
        }

        sigaddset(&sigset, SIGUSR1);
        sigprocmask(SIG_BLOCK, &sigset, NULL);
      } else {
            if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
          perror("2");
          return 2;
        }

        sigaddset(&sigset, SIGUSR2);
        sigprocmask(SIG_BLOCK, &sigset, NULL);
      }

      while(true) {
        int result = sigwait(&sigset, &sig);
        if(result == 0) {
          cout << "The caught signal is " << sig << endl;
        }
      }
      exit(0);

    } else {
      cout << "Registerd the handler " << pid << endl;
      handlers[i] = pid;
    }
  }

  //Registering the monitoring process
  if((pid = fork()) == 0) {
    sigset_t sigset;
    int sig;
    int result = 0;

    sigemptyset(&sigset);
    sigaddset(&sigset, SIGUSR1);
    sigaddset(&sigset, SIGUSR2);

    sigprocmask(SIG_BLOCK, &sigset, NULL);

    while(true) {
      int result = sigwait(&sigset, &sig);
      if(result == 0) {
        cout << "The monitored signal is " << sig << endl;
      } else {
        cout << "error" << endl;
      } 
    }

  } else {
    reporter = pid;
  }


  sleep(3);
  //Registering the signal generator
  for(int i=0; i<1; i++) {
    if((pid = fork()) == 0) {

      if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
        perror("1");
        return 1;
      }

      if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
        perror("2");
        return 2;
      }
      srand(time(0));
      while(true) {
        volatile int signal_id = rand()%2 + 1;
        cout << "Generating the signal " << signal_id << endl;
        if(signal_id == 1) {
          killpg(getpgid(getpid()), SIGUSR1);
        } else {
              killpg(getpgid(getpid()), SIGUSR2);
        }     
        int r = rand()%10 + 1;
        double s = (double)r/100;  
        sleep(s);
      }

      exit(0); 
    } else {
      cout << "Registered the sender " << pid << endl;
      senders[i] = pid;

    } 

  }


  while(w = wait(&status)) {
    cout << "Wait on PID " << w << endl;
  }

}



void signal_catcher_int(int the_sig) {
  //cout << "Handling the Ctrl C signal " << endl;
  for(int i=0; i<1; i++) {
    kill(senders[i],SIGKILL);
  }

  for(int i=0; i<4; i++) {
    kill(handlers[i],SIGKILL);
  }

  kill(reporter,SIGKILL);

  exit(3);
}

Qualche suggerimento?

Ecco un esempio dell'output

All'inizio

Registerd the handler 9544
Registerd the handler 9545
1
Registerd the handler 9546
Registerd the handler 9547
2
3
0
Registered the sender 9550
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 2
The caught signal is 12
The caught signal is 12
The monitored signal is 12
Generating the signal 2
Generating the signal 2
The caught signal is 12
The caught signal is 12
Generating the signal 1
The caught signal is 12
The monitored signal is 10
The monitored signal is 12
Generating the signal 1
Generating the signal 2
The caught signal is 12
Generating the signal 1
Generating the signal 2
10
The monitored signal is 10
The caught signal is 12
Generating the signal 1
The caught signal is 12
The monitored signal is GenThe caught signal is TheThe caught signal is 10
Generating the signal 2

Successivamente

The monitored signal is GenThe monitored signal is 10
Generating the signal 1
Generating the signal 2
The caught signal is 10
The caught signal is 10
The caught signal is 10
The caught signal is 12
Generating the signal 1
Generating the signal 2
Generating the signal 1
Generating the signal 1
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 1
The caught signal is 12
The caught signal is 10
The caught signal is 10
Generating the signal 2
Generating the signal 1
Generating the signal 1
Generating the signal 2
Generating the signal 1
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 1
Generating the signal 2
Generating the signal 1
Generating the signal 2
Generating the signal 2
The caught signal is 10
Generating the signal 2
Generating the signal 1
Generating the signal 1

Come puoi vedere inizialmente, il segnale è stato generato e gestito sia dai miei gestori di segnali che dai processi di monitoraggio. Ma in seguito il segnale è stato generato molto, ma non è stato abbastanza processi nella stessa ampiezza di prima. Inoltre ho potuto vedere molto meno elaborazione del segnale dal processo di monitoraggio

Qualcuno può fornirci qualche approfondimento. Cosa sta succedendo?

    
posta user34790 19.09.2012 - 03:47
fonte

1 risposta

2

Sei sicuro che il codice di monitoraggio non viene eseguito?

Nella tua sezione precedente: In seguito

The monitored signal is GenThe monitored signal is 10

Appare che std :: out che il processo di monitoraggio venga sovrascritto dall'altro processo biforcato. Ti suggerirei di scrivere l'output in file separati, magari nominati con PID e timestamp per comprendere appieno il comportamento che stai vedendo.

Il secondo problema che ho potuto vedere accadere è che il processo di monitoraggio biforcuto ha (per qualche motivo) smesso inaspettatamente. Per questo per vedere cosa sta succedendo nel sistema operativo, suggerirei di eseguire la parte superiore e osservare il comportamento del tuo programma e dei suoi processi biforcati.

    
risposta data 20.09.2012 - 00:28
fonte

Leggi altre domande sui tag