GNU/Linux >> Linux Esercitazione >  >> Linux

Il segnale può essere ignorato (perso)?

A parte il problema dei "troppi segnali", i segnali possono essere esplicitamente ignorati. Da man 2 signal :

If the signal signum is delivered to the process, then one of the
following happens:    
  *  If the disposition is set to SIG_IGN, then the signal is ignored.

I segnali possono anche essere bloccati. Da man 7 signal;

A signal may be blocked, which means that it will not be delivered
until it is later unblocked.  Between the time when it is generated
and when it is delivered a signal is said to be pending.

Sia i set di segnali bloccati che quelli ignorati vengono ereditati dai processi figli, quindi può accadere che il processo padre della tua applicazione ignori o blocchi uno di questi segnali.

Cosa succede quando vengono inviati più segnali prima che il processo abbia finito di gestire quelli precedenti? Dipende dal sistema operativo. Il signal(2) la manpage collegata sopra ne discute:

  • Il sistema V reimposterebbe la disposizione del segnale al valore predefinito. Peggio ancora, la consegna rapida di più segnali risulterebbe in chiamate ricorsive (?).
  • BSD bloccherebbe automaticamente il segnale finché il gestore non ha finito.
  • Su Linux, questo dipende dai flag di compilazione impostati per GNU libc , ma mi aspetto il comportamento di BSD.

Non puoi fidarti che ogni segnale inviato verrà consegnato. Ad esempio, il kernel Linux "coalesce" SIGCHLD se un processo impiega molto tempo a gestire SIGCHLD da un processo figlio terminato.

Per rispondere a un'altra parte della tua domanda, i segnali vengono "accodati" all'interno del kernel se un numero di segnali diversi arriva in un intervallo troppo breve.

Dovresti usare sigaction() per configurare il gestore del segnale con sa_sigaction membro di siginfo_t , impostando sa_mask membro dell'siginfo_t argomento con attenzione. Penso che questo significhi mascherare almeno tutti i segnali "asincroni". Secondo la pagina man di Linux sigaction() , maschererai anche il segnale gestito. Penso che dovresti impostare sa_flags membro di SA_SIGINFO, ma non ricordo perché ho questa superstizione. Credo che questo darà al tuo processo un gestore di segnale che rimane impostato senza race condition e che non viene interrotto dalla maggior parte degli altri segnali.

Scrivi la tua funzione di gestore del segnale molto, molto attentamente. Fondamentalmente basta impostare una variabile globale per indicare che un segnale è stato catturato e fare in modo che il resto del processo si occupi dell'azione desiderata per quel segnale. In questo modo i segnali verranno mascherati per il minor tempo possibile.

Inoltre, ti consigliamo di testare molto accuratamente il tuo codice di gestione del segnale. Mettilo in un piccolo processo di test e invia il maggior numero possibile di segnali SIGUSR1 e SIGUSR2, magari da 2 o 3 programmi di invio di segnali speciali. Mescola anche altri segnali, dopo esserti assicurato che il tuo codice può gestire SIGUSR1 e SIGUSR2 in modo rapido e corretto. Preparati per un debugging difficile.

Se stai usando Linux e solo Linux, potresti pensare di usare signalfd() per creare un descrittore di file che puoi select() o poll per ricevere quei segnali. Usando signalfd() potrebbe semplificare il debug.


È garantito che venga consegnato un segnale, nel senso che se un processo chiama con successo kill , quindi il bersaglio riceverà il segnale. Questo è asincrono:il mittente non ha modo di sapere quando il segnale viene ricevuto o elaborato. Tuttavia, ciò non garantisce che il segnale verrà consegnato. Il bersaglio potrebbe morire prima di poter elaborare il segnale. Se il bersaglio sta ignorando il segnale nel momento in cui viene consegnato, il segnale non avrà alcun effetto. Se il target riceve più istanze dello stesso numero di segnale prima di poterle elaborare, i segnali possono (e di solito vengono) uniti:se invii lo stesso segnale due volte a un processo, non puoi sapere se il processo riceverà il segnale una o due volte. I segnali sono principalmente progettati per terminare un processo o come un modo per attirare l'attenzione di un processo, non sono progettati per la comunicazione in quanto tale.

Se hai bisogno di una consegna affidabile, allora hai bisogno di un meccanismo di comunicazione diverso. Esistono due principali meccanismi di comunicazione tra i processi:una pipe consente la comunicazione unidirezionale; un socket consente la comunicazione bidirezionale e connessioni multiple allo stesso server. Se hai bisogno che il target elabori tante notifiche quante ne invii, invia byte su una pipe.


Linux
  1. Segnali Linux – Esempio di programma C per catturare i segnali (SIGINT, SIGKILL, SIGSTOP, ecc.)

  2. Nozioni di base sui segnali di Linux – Parte I

  3. Python - Intrappola tutti i segnali

  4. Accodamento del segnale in C

  5. Chi utilizza i segnali POSIX in tempo reale e perché?

13 modi in cui puoi aiutare Linux

Impossibile accedere alle cartelle montate da sshfs dopo la sospensione (o quando si perde la connessione)

Quali numeri di segnale funzionano con il comando kill?

Può ',,' essere alias di '..'?

Come posso monitorare il disco io?

Cosa può causare un segnale 11?