2012-10-29 18 views
5

C'è un modo per bloccare determinati segnali e sbloccare altri segnali nello stesso set? Non riesco a capirlo!thread posix blocco segnale e sblocco

Un esempio

sigset_t set; 
sigemptyset(&set); 

sigaddset(&set, SIGUSR1); 
// Block signal SIGUSR1 in this thread 
pthread_sigmask(SIG_BLOCK, &set, NULL); 
sigaddset(&set, SIGALRM); 
// Listen to signal SIGUSR2 
pthread_sigmask(SIG_UNBLOCK, &set, NULL); 


pthread_t printer_thread1, printer_thread2; 
pthread_create(&printer_thread1, NULL, print, (void *)&f1); 
pthread_create(&printer_thread2, NULL, print, (void *)&f2); 

bool tl = true; 
while(1) 
{ 
    if(tl) 
    { 
     // thread1 does something 
     kill(pid, SIGUSR1); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
    else 
    { 
     // thread2 does something 
     kill(pid, SIGUSR2); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
} 

non mi è permesso di utilizzare mutexs, semafori ecc solo segnali.

Qualcuno può aiutare? :)

+0

Non stai prima bloccando e sbloccando SIGUSR1 qui? Al momento di UNBLOCK, il set contiene sia SIGUSR1 che SIGALRM. – amaurea

risposta

9

C'è un modo per bloccare determinati segnali e sbloccare altri segnali nello stesso set?

Con pthread_sigmask, è possibile scegliere di:

  • aggiungere una serie di segnali alla serie di segnali bloccati, utilizzando la costante SIG_BLOCK
  • rimuovere una serie di segnali alla serie di blocco segnali, utilizzando la costante SIG_UNBLOCK
  • definire l'insieme dei segnali che devono essere bloccati, utilizzando la costante SIG_SET

In altre parole, esiste un set corrente di segnali bloccati per il thread e è possibile modificarlo come specificato sopra, un'operazione alla volta.

Il punto importante è che i thread appena creati ereditano la maschera di segnale del thread di creazione, quindi è possibile impostare la maschera del nuovo thread appena prima di crearlo o nella funzione in cui verrà eseguito il nuovo thread, a proprio piacimento .

Per quanto riguarda il tuo esempio, suppongo che si sta tentando di avere printer_thread1 blocco SIGUSR2 e SIGALRM, e hanno printer_thread2 blocco SIGUSR1 e SIGALRM, e hanno il blocco thread principale SIGUSR1 e SIGUSR2, in modo che ogni thread può inviare un segnale che sarà essere catturati da un singolo thread (senza il codice di print, f1 e f2, è impossibile sapere con certezza qual è il tuo intento nel tuo esempio).

Si dovrebbe essere in grado di realizzare che il seguente codice:

sigset_t set; 
pthread_t printer_thread1, printer_thread2; 


// Block signal SIGUSR1 & SIGALRM in printer_thread1 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 
sigaddset(&set, SIGALRM); 
pthread_sigmask(SIG_SET, &set, NULL); 
pthread_create(&printer_thread1, NULL, print, (void *)&f1); 

// Block signal SIGUSR2 & SIGALRM in printer_thread2 
sigaddset(&set, SIGUSR2); 
sigaddset(&set, SIGALRM); 
pthread_sigmask(SIG_SET, &set, NULL); 
pthread_create(&printer_thread2, NULL, print, (void *)&f2); 

// Block signal SIGUSR1 & SIGUSR2 in the main thread 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 
sigaddset(&set, SIGUSR2); 
// Listen to signal SIGALRM 
pthread_sigmask(SIG_SET, &set, NULL); 


bool tl = true; 
while(1) 
{ 
    if(tl) 
    { 
     // thread1 does something 
     kill(pid, SIGUSR1); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
    else 
    { 
     // thread2 does something 
     kill(pid, SIGUSR2); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
} 

vedere queste pagine man:

per ulteriori dettagli.

+0

Grazie, ha senso, ma in realtà non funziona con i thread della stampante. Ma capisco come funzionano le maschere ora. – Max

1

Penso che ciò che si vuole fare qui è

// Block signal SIGUSR1 in this thread 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 
pthread_sigmask(SIG_BLOCK, &set, NULL); 

// Listen to signal SIGALRM 
sigemptyset(&set); 
sigaddset(&set, SIGALRM); 
pthread_sigmask(SIG_UNBLOCK, &set, NULL); 

Il set viene utilizzato solo per indicare cosa per bloccare o sbloccare. Una volta passato al comando, sei libero di resettarlo e creare un'altra maschera di segnale. Se salti il ​​sigemptyset, il set conterrà ancora SIGUSR1, che verrà successivamente sbloccato. Bene, penso che sia così che funziona, almeno - è passato molto tempo da quando ho usato i segnali.

Problemi correlati