2009-07-28 10 views
6

Se dico Perl ad ignorare in modo esplicito un segnale, SIGINT non ha alcun effetto:Qual è la differenza tra ignorare un segnale e dirgli di non fare nulla in Perl?

$SIG{INT} = 'IGNORE'; 
my $count = 0; 
say $count++ and sleep 1 while 1; 

Poi premere Control-C, invece, ovviamente, non ha alcun effetto. Se, d'altra parte, dico di non fare nulla:

$SIG{INT} = sub { }; 
my $count = 0; 
say $count++ and sleep 1 while 1; 

Quindi premere Control-C ha effetto! Riattiva il programma dalla sua chiamata Sleep() e incrementa immediatamente il conteggio. Qual è la differenza tra ignorare un segnale e dirgli di non fare nulla?

Nel mio programma, mi piacerebbe avere il codice eseguito su SIGINT, senza facendolo interrompere nulla. Voglio qualcosa di simile:

$SIG{INT} = sub { say "Caught SIGINT!"; return IGNORED; }; # runs without disrupting sleep 
+0

Come è possibile che il tuo gestore di segnale funzioni senza interrompere ciò che è attualmente in esecuzione? La logica di gestione del segnale dovrà sapere cosa dovrebbe accadere PRIMA che il segnale si verifichi. – innaM

risposta

1

Non certo perché non funziona come ci si aspetta, ma normalmente quando cerco di fare cose simili Ho anche intrappolare il segnale TERM, oltre al segnale di INT.

13

Qual è la differenza tra ignorare un segnale e dirgli di non fare nulla?

Il tuo gestore "non fare nulla" è ancora invocato quando il segnale viene consegnato, interrompendo la chiamata sleep in questo caso. I segnali ignorati, d'altra parte, vengono semplicemente scartati dal sistema, non avendo alcun effetto sul processo.

Vedere here per un riferimento specifico C ma più completo.

6

Un sacco di chiamate di sistema possono essere interrotte dall'erogazione del segnale. Di solito è possibile controllare $! (aka errno) per vedere se è EINTR e agire per riprovare la chiamata di sistema fallita.

Se è importante per te che determinate sezioni del tuo codice (in questo caso, la tua chiamata a sleep()) non siano interrotte, puoi utilizzare POSIX::sigprocmask per bloccare i segnali mentre ti trovi nella sezione critica. Tutti i segnali ricevuti dall'applicazione verranno messi in coda fino a quando non verranno sbloccati, a quel punto verranno consegnati. Sono abbastanza sicuro che ci sia qualche semantica divertente quando vengono bloccati più segnali di un particolare tipo (penso che possano fondersi in un singolo segnale).

Ecco un nice primer da IBM sulle funzioni di rientro e include un piccolo campione con sigprocmask.

+0

+1. La mia comprensione è che la maggior parte delle varianti UNIX fonderà assolutamente più segnali dello stesso tipo. Quindi quando vedi un segnale XYZ, tutto ciò che puoi essere certo è che XYZ è stato sollevato * almeno una volta *. –

Problemi correlati