Signal
Et signal er en hendelse som genereres for å varsle en prosess eller tråd om at det har kommet en viktig situasjon. Når en prosess eller tråd har mottatt et signal, vil prosessen eller tråden stoppe det den gjør og ta noen tiltak. Signal kan være nyttig for kommunikasjon mellom prosesser.
Standardsignaler
Signalene er definert i overskriftsfilen signal.h som en makrokonstant. Signalnavnet har startet med en "sig" og etterfulgt av en kort beskrivelse av signalet. Så hvert signal har en unik numerisk verdi. Programmet ditt skal alltid bruke navnet på signalene, ikke signalnummeret. Årsaken er at signalnummeret kan variere i henhold til systemet, men betydningen av navn vil være standard.
Makroen NSIG er det totale antallet signal definert. Verdien av NSIG er en større enn det totale antallet signal definert (alle signalnumre tildeles fortløpende).
Følgende er standardsignalene:
Signalnavn | Beskrivelse |
Sukk | Hang-up prosessen. Sukksignalet brukes til å rapportere frakobling av brukerens terminal, muligens fordi en ekstern tilkobling går tapt eller henger på. |
Sigint | Avbryte prosessen. Når brukeren skriver inn intrekarakteren (normalt Ctrl + C) sendes SIGINT -signalet. |
Sigquit | Avslutt prosessen. Når brukeren skriver ut at Quit -tegnet (normalt Ctrl + \) sendes SIGQUIT -signalet. |
Sigill | Ulovlig instruksjon. Når det blir gjort et forsøk på å utføre søppel eller privilegert instruksjon, genereres Sigill -signalet. Sigill kan også genereres når bunken overfører, eller når systemet har problemer med å kjøre en signalbehandler. |
Sigtrap | Sporfelle. En instruksjon i breakpoint og annen felleinstruksjon vil generere Sigtrap -signalet. Debuggeren bruker dette signalet. |
Sigabrt | Avbryte. Sigabrt -signalet genereres når abort () -funksjonen kalles. Dette signalet indikerer en feil som blir oppdaget av selve programmet og rapportert av Abort () -funksjonsanropet. |
Sigfpe | Flytende punkt unntak. Når en dødelig aritmetisk feil oppstod, genereres SIGFPE -signalet. |
SIGUSR1 og SIGUSR2 | Signalene Sigusr1 og Sigusr2 kan brukes som du ønsker. Det er nyttig å skrive en signalbehandler for dem i programmet som mottar signalet for enkel kommunikasjon mellom prosessen. |
Standard handling av signaler
Hvert signal har en standardhandling, ett av følgende:
Begrep: Prosessen avsluttes.
Kjerne: Prosessen vil avslutte og produsere en kjernedump -fil.
Ign: Prosessen vil ignorere signalet.
Stoppe: Prosessen vil stoppe.
Forts: Prosessen vil fortsette fra å bli stoppet.
Standardhandling kan endres ved hjelp av behandlerfunksjonen. Noen signalets standardhandling kan ikke endres. Sigkill og Sigabrt signalets standardhandling kan ikke endres eller ignorerer.
Signalhåndtering
Hvis en prosess mottar et signal, har prosessen et valg av handling for den slags signal. Prosessen kan ignorere signalet, kan spesifisere en behandlerfunksjon, eller godta standardhandlingen for den slags signal.
Vi kan håndtere signalet ved hjelp av signal eller Sigaction funksjon. Her ser vi hvordan de enkleste signal() Funksjon brukes til håndteringssignaler.
int signal () (int Signum, void (*func) (int))De signal() vil ringe func funksjon hvis prosessen mottar et signal signum. De signal() Returnerer en peker for å fungere func Hvis vellykket eller den returnerer en feil til Errno og -1 ellers.
De func Peker kan ha tre verdier:
Grunnleggende signalbehandlereksempel
#inkludereI skjermbildet av output fra eksempel1.C, vi kan se at i hovedfunksjonen utføres uendelig sløyfe. Når brukeren skrev CTRL+C, blir hovedfunksjonens utførelsesstopp og førerfunksjonen til signalet påkalt. Etter fullføring av behandlerfunksjonen gjenopptok hovedfunksjonens utførelse. Når brukertypen skrev Ctrl+\, avsluttes prosessen.
Ignorer signaler eksempel
#inkludereHer er behandlerfunksjonen registrert til Sig_ign () Funksjon for å ignorere signalaksjonen. Så når brukeren skrev Ctrl+C, Sigint signalet genererer, men handlingen blir ignorert.
REGISTER SIGNAL HANDLER Eksempel
#inkludereI skjermbildet av output fra eksempel3.C, vi kan se at når brukeren første gang skrev CTRL+C, påkalt behandlerfunksjonen. I behandlerfunksjonen registrerer signalbehandleren seg til SIG_DFL For standard handling av signalet. Når brukeren skrev inn Ctrl+C for andre gang, avsluttes prosessen som er standardhandlingen til Sigint signal.
Sende signaler:
En prosess kan også eksplisitt sende signaler til seg selv eller til en annen prosess. Raise () og Kill () -funksjonen kan brukes til å sende signaler. Begge funksjonene er erklært i signal.H headerfil.
int Raise (int Signum)Raise () -funksjonen som brukes til å sende signal signum til anropsprosessen (seg selv). Den returnerer null hvis den lykkes og en ikke -nullverdi hvis den mislykkes.
int kill (pid_t pid, int signum)Killfunksjonen som brukes til å sende et signal signum til en prosess- eller prosessgruppe spesifisert av PID.
SIGUSR1 signalbehandlereksempel
#inkludereHer sender prosessen SIGUSR1 -signal til seg selv ved hjelp av Raise () -funksjonen.
Raise with Kill Exempel -programmet
#inkludereHer sendes prosessen Sigusr1 signal til seg selv ved bruk av drepe() funksjon. getPid () brukes til å få prosess -ID for seg selv.
I neste eksempel vil vi se hvordan foreldre og barn prosesser kommuniserer (inter prosesskommunikasjon) ved bruk av drepe() og signalfunksjon.
Foreldre barnekommunikasjon med signaler
#inkludereHer, gaffel() Funksjon skaper barneprosess og returnerer null til barneprosess og barneprosess -ID til overordnet prosess. Så PID har blitt sjekket for å avgjøre foreldre- og barneprosess. I overordnet prosess er den sovet i 1 sekund slik at barneprosessen kan registrere signalbehandlerfunksjon og vente på signalet fra overordnede. Etter 1 sekunders foreldreprosess sendes Sigusr1 signal til barneprosess og vent på responssignalet fra barnet. I barneprosessen venter det først på signal fra foreldre, og når signalet mottas, påkalles behandlerfunksjonen. Fra behandlerfunksjonen sender barneprosessen en annen Sigusr1 signal til foreldre. Her GetPPID () Funksjon brukes til å få foreldreprosess -ID.
Konklusjon
Signal i Linux er et stort tema. I denne artikkelen har vi sett hvordan vi skal håndtere signal fra det helt grunnleggende, og også få kunnskap om hvordan signalet genererer, hvordan en prosess kan sende signal til seg selv og annen prosess, hvordan signal kan brukes til kommunikasjon mellom prosesser.