2017-06-22 2 views
0

J'essaie d'envoyer des signaux SIGUSR1/SIGUSR2 entre plusieurs processus en utilisant un gestionnaire personnalisé, mais mon gestionnaire ne fonctionne pas. Il n'imprime aucun message de débogage ou quoi que ce soit.Gestionnaire de signal sous Linux utilisant sigaction (C++)

Ici, je suis entrain de créer 8 processus et d'essayer de définir un gestionnaire personnalisé en utilisant la fonction set_sigaction:

int main(){ 
    pidArray = (int *)mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE,MAP_ANONYMOUS | MAP_SHARED, -1, 0);//Self pid 
    pidArray2 = (int *)mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE,MAP_ANONYMOUS | MAP_SHARED, -1, 0);//Child pid 
    counter = (int *)mmap(NULL, MMAP_SIZE2, PROT_READ | PROT_WRITE,MAP_ANONYMOUS | MAP_SHARED, -1, 0); 
    counter[0]=0; 
    counter[1]=0; 
    pid_t pid, pid2; 
    int counter = 1; 
    pidArray[0]=getpid(); 
    pid = fork(); //1 
    if(pid == 0){ 
     pid = fork(); //2 
     if(pid != 0){ 
      pidArray[1]=getpid(); 
      pidArray2[1]=pid; 
     } 
     if(pid == 0){ 
      pid2 = getpid(); 
      pidArray[2]=pid2; 
      pid=fork(); //4 
      if(pid == 0){ 
       pidArray[4] = getpid(); 
       pid=fork(); //5 
       if(pid==0){ 
        pidArray[5] = getpid(); 
        pidArray2[5] = 0; 
       } 
       else 
        pidArray2[4] = pid; 
      } 
     if(pid2 == getpid()){ 
      pid2 = fork(); //3 
      if(pid2!=0){ 
       pid = setpgid(pid,pid2); 
      } 
      else{ 
       pidArray[3]=getpid(); 
       pid=fork(); //6 
       if(pid==0){ 
        pidArray[6]=getpid(); 
        pid=fork(); //7 
        if(pid==0){ 
         pidArray[7]=getpid(); 
         pid=fork(); //8 
         if(pid!=0) 
          pidArray2[7]=pid; 
         else{ 
          pidArray[8]=getpid(); 
          pidArray2[8]=pidArray[1]; 
         } 

        } 
        else 
         pidArray2[6]=pid; 
       } 
       else 
        pidArray2[3]=pid; 
      } 
     }   
     } 
    } 

    set_sigaction(SIGUSR1); 

    sleep(5); 

    if(getpid()==pidArray[1]) 
     kill(pidArray[0],SIGTERM); 
    if(getpid()==pidArray[1]){ 
     send_signal(pidArray[1]); 
    } 
    sleep(100); 
    return 0; 

Voici fonction set_sigaction:

static int set_sigaction(int signo) 
{ 
    struct sigaction sa; 
    memset(&sa, 0, sizeof(struct sigaction)); 
    sa.sa_sigaction = handler; 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = SA_SIGINFO; 
    return sigaction(signo, &sa, NULL); 
} 

Et voici le gestionnaire:

static void handler(int signo, siginfo_t* si, void* ucontext){ 
    int k; 
    int i; 
    pid_t pid = getpid(); 
    for(i=1;i<9;i++){ 
     if(pidArray[i]==pid) 
      k=i; 
    } 
    time_t rawtime; 
    time (&rawtime); 
    cout << k << " " << pid << " Got USR1 " << ctime (&rawtime) << "\n"; 
    send_signal(getpid()); 
} 

Ma fonction send_signal me donne ce message, ce qui signifie qu'elle envoie SIGUSR1 si gnal au deuxième processus:

1 3156 Envoyer USR1 Jeu Juin 22 18:04:54 2017

Je pense que le problème est comment créer plusieurs processus ou comment je configurer mon gestionnaire.

+1

Vous devez être prudent avec les signaux POSIX: quand un feu de signalisation, il peut tout interrompre (même appel noyau). Cela signifie que, lors de la manipulation du signal, vous êtes potentiellement dans un état incorrect, vous pouvez avoir des données de course, ... Dans le gestionnaire de signal, vous devriez essayer de sortir aussi vite que possible et vous devriez la plupart du temps effet (comme E/S). – nefas

+0

Merci pour vos conseils, mais si mon gestionnaire n'a qu'un message de débogage. il ne l'imprimera toujours pas. – Dmitry

+0

que fait «send_signal»? – nefas

Répondre

0

que fait send_signal? Essayez d'envoyer le signal en utilisant la fonction kill comme:

kill (pidArray [1], SIGUSR1)

+0

ouais, comme ça, mais pour des processus différents – Dmitry