Segnale
Un segnale è un evento che viene generato per avvisare un processo o thread che è arrivata una situazione importante. Quando un processo o un thread ha ricevuto un segnale, il processo o il thread fermeranno ciò che sta facendo e intraprende un po 'di azione. Il segnale può essere utile per la comunicazione tra processo.
Segnali standard
I segnali sono definiti nel file di intestazione segnale.H Come macro costante. Il nome del segnale è iniziato con un "sig" e seguito da una breve descrizione del segnale. Quindi, ogni segnale ha un valore numerico unico. Il tuo programma dovrebbe sempre utilizzare il nome dei segnali, non il numero di segnali. Il motivo è che il numero del segnale può differire in base al sistema, ma il significato dei nomi sarà standard.
La macro Nsig è il numero totale di segnale definito. Il valore di Nsig è uno maggiore del numero totale di segnale definito (tutti i numeri del segnale sono allocati consecutivamente).
Di seguito sono riportati i segnali standard:
Nome del segnale | Descrizione |
Sighup | Aggancia il processo. Il segnale di sospiro viene utilizzato per segnalare la disconnessione del terminale dell'utente, possibilmente perché una connessione remota viene persa o riattaccata. |
Sigint | Interrompere il processo. Quando l'utente digita il carattere intr (normalmente Ctrl + C) viene inviato il segnale Sigint. |
SIGQUIT | Lascia il processo. Quando l'utente digita il carattere di lasciare (normalmente Ctrl + \) viene inviato il segnale SIGQUIT. |
Sigill | Istruzione illegale. Quando viene fatto un tentativo di eseguire imbotti di immondizia o privilegiata, viene generato il segnale SIGIll. Inoltre, la sigill può essere generata quando lo stack trabocca o quando il sistema ha difficoltà a eseguire un gestore del segnale. |
SigTrap | Traccia trappola. Un'istruzione di breakpoint e altre istruzioni trap genereranno il segnale SigTrap. Il debugger utilizza questo segnale. |
Sigabrt | Abortire. Il segnale Sigabrt viene generato quando viene chiamata la funzione abort (). Questo segnale indica un errore rilevato dal programma stesso e riportato dalla chiamata di funzione Abort (). |
Sigfpe | Eccezione a punta mobile. Quando si è verificato un errore aritmetico fatale, viene generato il segnale SIGFPE. |
Sigusr1 e Sigusr2 | I segnali Sigusr1 e Sigusr2 possono essere usati come desideri. È utile scrivere un gestore del segnale per loro nel programma che riceve il segnale per una semplice comunicazione tra process. |
Azione predefinita dei segnali
Ogni segnale ha un'azione predefinita, una delle seguenti:
Termine: Il processo terminerà.
Nucleo: Il processo terminerà e produrrà un file di dump principale.
IGN: Il processo ignorerà il segnale.
Fermare: Il processo si fermerà.
Cont: Il processo continuerà a essere fermato.
L'azione predefinita può essere modificata utilizzando la funzione Handler. L'azione predefinita di qualche segnale non può essere modificata. Sigkill E Sigabrt L'azione predefinita del segnale non può essere modificata o ignorata.
Gestione del segnale
Se un processo riceve un segnale, il processo ha una scelta di azione per quel tipo di segnale. Il processo può ignorare il segnale, può specificare una funzione di gestore o accettare l'azione predefinita per quel tipo di segnale.
Possiamo gestire il segnale usando segnale O Sigazione funzione. Qui vediamo come il più semplice segnale() La funzione viene utilizzata per la gestione dei segnali.
INT SIGNAL () (int Signum, void (*func) (int))IL segnale() chiamerò il Func funzione se il processo riceve un segnale Signor. IL segnale() Restituisce un puntatore per funzionare Func in caso di successo o restituisce un errore a errno e -1 altrimenti.
IL Func Il puntatore può avere tre valori:
Esempio di gestore del segnale di base
#includereNello screenshot dell'output di Esempio1.C, possiamo vedere che nella funzione principale infinite loop sta eseguendo. Quando l'utente ha digitato CTRL+C, viene invocata l'esecuzione della funzione principale e la funzione gestore del segnale. Dopo il completamento della funzione gestore, l'esecuzione della funzione principale è ripresa. Quando il tipo di utente ha digitato CTRL+\, il processo viene lasciato.
Ignora l'esempio dei segnali
#includereQui la funzione gestore è registrata a Sig_ign () funzione per ignorare l'azione del segnale. Quindi, quando l'utente ha digitato Ctrl+C, Sigint Il segnale sta generando ma l'azione viene ignorata.
Esempio di gestore di segnale Reregister
#includereNello screenshot dell'output di Esempio3.C, possiamo vedere che quando l'utente ha digitato la prima volta Ctrl+C, la funzione gestore invocata. Nella funzione gestore, il gestore del segnale si registra a Sig_dfl Per l'azione predefinita del segnale. Quando l'utente ha digitato Ctrl+C per la seconda volta, il processo viene terminato che è l'azione predefinita di Sigint segnale.
Invio di segnali:
Un processo può anche inviare esplicitamente segnali a se stesso o a un altro processo. La funzione di sollevare () e kill () può essere utilizzata per l'invio di segnali. Entrambe le funzioni sono dichiarate nel segnale.File di intestazione H.
int sollevare (int Signum)La funzione di sollevamento () utilizzata per l'invio del segnale Signor al processo di chiamata (se stesso). Restituisce zero in caso di successo e un valore diverso da zero se fallisce.
int kill (pid_t pid, int Signum)La funzione di uccisione utilizzata per inviare un segnale Signor a un processo o gruppo di processo specificato da pid.
Esempio di gestore del segnale Sigusr1
#includereQui, il processo invia il segnale Sigusr1 a se stesso usando la funzione di alza ().
Raccolta con il programma di esempio di uccisione
#includereQui, il processo invia Sigusr1 segnale a se stesso usando uccisione() funzione. getpid () è usato per ottenere l'ID processo di se stesso.
Nel prossimo esempio vedremo come comunica i processi dei genitori e dei figli uccisione() e funzione del segnale.
Comunicazione figlio genitore con segnali
#includereQui, forchetta() La funzione crea il processo figlio e restituire zero al processo figlio e dell'ID processo figlio al processo genitore. Quindi, il PID è stato verificato per decidere il processo dei genitori e del figlio. Nel processo del genitore, è dormito per 1 secondo in modo che il processo figlio possa registrare la funzione del gestore del segnale e attendere il segnale dal genitore. Dopo 1 secondo processo genitore inviare Sigusr1 segnale al processo di bambino e attendere il segnale di risposta da figlio. Nel processo figlio, prima è in attesa del segnale dal genitore e quando viene ricevuto il segnale, viene invocata la funzione del gestore. Dalla funzione gestore, il processo figlio ne invia un altro Sigusr1 segnale al genitore. Qui getppid () La funzione viene utilizzata per ottenere l'ID del processo genitore.
Conclusione
Il segnale in Linux è un grande argomento. In questo articolo abbiamo visto come gestire il segnale dal molto semplice e anche conoscere come generare il segnale, come un processo può inviare il segnale a se stesso e altro processo, come il segnale può essere utilizzato per la comunicazione tra processi.