2014-12-01 24 views
5

Ho questo codice dove uso sigaddset e sigaction. Tuttavia se commento segaddset il risultato è lo stessoPer che cosa si usa sigaddset?

struct sigaction act; 

    act.sa_handler = process_alarm; 
    act.sa_flags = 0;   
    sigemptyset(&act.sa_mask); 
    //sigaddset(&act.sa_mask, SIGINT); 

    sigaction(SIGALRM, &act, NULL); 

    for(;;) 
    { 
     alarm(3); 
     pause(); 
    } 

Perché devo usarlo?

+1

hai provato a premere 'CTRL + C' quando esegui il tuo programma con/senza commentare' sigaddset() '? –

+0

@SouravGhosh yes ma, come indicato in altre risposte, il gestore degli allarmi si attiva rapidamente per notarne l'effetto. Aggiunta di un 'sleep (10)' nel gestore e posso vedere la differenza :) – NeDark

risposta

12

State facendo 2 cose qui:

  1. compilazione di un sigset_t. Un sigset_t è solo una raccolta di valori per i segnali e viene utilizzato in varie chiamate di sistema. È possibile:

    • Crea un sigset_t vuota (sigemptyset()
    • Aggiungi un segnale al set (sigaddset())
    • Rimuovere un segnale al set (sigdelset())
    • etc. ..
  2. Impostazione della maschera di segnale per il gestore di segnale.Lo fai manipolando il membro quando si imposta un gestore di segnale con una chiamata a sigaction().

La maschera di un gestore di segnale segnale significa che mentre il gestore di segnale è in esecuzione, i segnali che si trovano nella maschera sarà bloccato - cioè tali segnali non verranno trattati purché siano bloccate. Quando il gestore del segnale è finito, i segnali in saranno sbloccati. Un segnale che è bloccato non è "perso", sarà gestito quando quel particolare segnale è sbloccato di nuovo.

Il sigaddset(&act.sa_mask, SIGINT); indica che il segnale SIGINT non può verificarsi mentre è in esecuzione il codice per il gestore SIGALRM.

D'altra parte, se si commenta sigaddset(&act.sa_mask, SIGINT);, si rimane solo una lista vuota di segnali creati con sigemptyset(&act.sa_mask);. Quindi, qualsiasi segnale che si verifica mentre la funzione del gestore SIGALRM è in esecuzione potrebbe prevenire quel gestore ed eseguire il gestore di segnale per quell'altro segnale.

Per un SIGINT, normalmente non si notano differenze con i test manuali: è improbabile che si riesca a premere CTRL-C esattamente quando il gestore di SIGALRM è in esecuzione e il gestore SIGALRM probabilmente esegue abbastanza rapidamente da non notare se il SIGINT è stato leggermente ritardato.

0

sigaddset viene utilizzato per aggiungere la maschera di segnale corrispondente alla variabile sigset_t.

In sigaction, non è necessario. Puoi usarlo quando stai usando la sigprocmask che serve per bloccare il segnale che menzioniamo in quella variabile.

5

I segnali sono gestiti tramite il tipo sigset_t. Diverse operazioni sono disponibili per segnali insiemi:

  • creare un insieme S vuoto tramite sigemptyset, S = ∅
  • aggiungere un segnale s per un insieme S tramite sigaddset, S = S∪ {s}
  • rimuovi un segnale s da un set tramite sigdelset, S = S \ {s}
  • creare l'insieme di tutti i segnali possibili tramite sigfillset.
  • test è un segnale s è in un dato set S tramite sigismember, s∈S?

Una tale serie viene utilizzato in luoghi diversi: impostazione di una nuova maschera segnale di processo, il blocco ambientato durante la manipolazione del segnale, che richiede la serie di segnali in attesa, ecc

Se si desidera catturare segnali diversi, potrebbe sembrare che alcune funzioni di cattura non debbano essere interrotte con altre, quindi è possibile aggiungere una serie di segnali da bloccare durante l'erogazione di un determinato segnale. In realtà hai deciso (quando non commentato) di bloccare SIGINT durante la consegna di SIGALRM. Quindi puoi solo osservarlo inviando un SIGINT durante l'esecuzione del gestore; che è difficile da realizzare.

Un esempio in cui può essere importante?

Supponiamo che il gestore di SIGUSR1 modifichi una determinata struttura dati e che il gestore di SIGUSR2 utilizzi la stessa struttura dati. È molto importante che entrambi i gestori non siano concomitanti, uno può essere eseguito dopo l'altro ma probabilmente non si desidera essere interrotti da uno durante la consegna dell'altro. Il tuo codice è auto-concomitante, affermare che anche nel caso di un solo thread, i segnali possono portare alla concorrenza.