C Programmering

Sådan bruges signalhåndterere på C-sprog?

Sådan bruges signalhåndterere på C-sprog?
I denne artikel vil vi vise dig, hvordan du bruger signalhåndterere i Linux ved hjælp af C-sprog. Men først vil vi diskutere, hvad der er signal, hvordan det vil generere nogle almindelige signaler, som du kan bruge i dit program, og så vil vi se, hvordan forskellige signaler kan håndteres af et program, mens programmet udføres. Så lad os starte.

Signal

Et signal er en begivenhed, der genereres for at underrette en proces eller tråd om, at en vigtig situation er ankommet. Når en proces eller tråd har modtaget et signal, stopper processen eller tråden, hvad den laver, og foretager sig noget. Signal kan være nyttigt til kommunikation mellem processer.

Standard signaler

Signalerne er defineret i headerfilen signal.h som en makrokonstant. Signalnavnet er startet med et “SIG” og efterfulgt af en kort beskrivelse af signalet. Så hvert signal har en unik numerisk værdi. Dit program skal altid bruge navnet på signalerne, ikke signalnummeret. Årsagen er, at signalnummeret kan variere alt efter system, men betydningen af ​​navne vil være standard.

Makroen NSIG er det samlede antal definerede signal. Værdien af NSIG er et større end det samlede antal definerede signal (Alle signalnumre tildeles fortløbende).

Følgende er standardsignaler:

Signalnavn Beskrivelse
SIGHUP Læg processen op. SIGHUP-signalet bruges til at rapportere afbrydelse af brugerens terminal, muligvis fordi en fjernforbindelse går tabt eller lægger på.
SIGINT Afbryd processen. Når brugeren skriver INTR-tegnet (normalt Ctrl + C) sendes SIGINT-signalet.
SIGQUIT Afslut processen. Når brugeren skriver QUIT-tegnet (normalt Ctrl + \), sendes SIGQUIT-signalet.
SIGILL Ulovlig instruktion. Når der forsøges at udføre skrald eller privilegeret instruktion, genereres SIGILL-signalet. SIGILL kan også genereres, når stakken løber over, eller når systemet har problemer med at køre en signalbehandler.
SIGTRAP Sporfælde. En breakpoint-instruktion og anden fældeinstruktion genererer SIGTRAP-signalet. Fejlfindingsprogrammet bruger dette signal.
SIGABRT Abort. SIGABRT-signalet genereres, når funktionen afbryde () kaldes. Dette signal indikerer en fejl, der registreres af selve programmet og rapporteres af funktionen afbryd () -opkald.
SIGFPE Flydende undtagelse. Når der opstod en fatal aritmetisk fejl, genereres SIGFPE-signalet.
SIGUSR1 og SIGUSR2 Signalerne SIGUSR1 og SIGUSR2 kan bruges som du ønsker. Det er nyttigt at skrive en signalbehandler til dem i programmet, der modtager signalet til enkel inter-proces kommunikation.

Standardhandling af signaler

Hvert signal har en standardhandling, en af ​​følgende:

Semester: Processen afsluttes.
Kerne: Processen afsluttes og producerer en kerne-dumpfil.
Tænd: Processen ignorerer signalet.
Hold op: Processen stopper.
Fortsat: Processen vil fortsat blive stoppet.

Standardhandling kan ændres ved hjælp af handlerfunktion. Nogle signalets standardhandling kan ikke ændres. SIGKILL og SIGABRT signalets standardhandling kan ikke ændres eller ignoreres.

Signalhåndtering

Hvis en proces modtager et signal, har processen et valg af handling for den slags signal. Processen kan ignorere signalet, kan specificere en behandlingsfunktion eller acceptere standardhandlingen for den slags signal.

Vi kan håndtere signalet ved hjælp af signal eller sigaction fungere. Her ser vi, hvordan det enkleste signal() funktion bruges til håndtering af signaler.

int signal () (int signum, void (* func) (int))

Det signal() vil kalde func funktion, hvis processen modtager et signal signum. Det signal() returnerer en markør, der skal fungere func hvis det lykkes, eller hvis det returnerer en fejl til errno og -1 ellers.

Det func markøren kan have tre værdier:

  1. SIG_DFL: Det er en markør til systemets standardfunktion SIG_DFL (), erklæret i h header-fil. Det bruges til at udføre standardhandling af signalet.
  2. SIG_IGN: Det er en pointer til system ignorere funktion SIG_IGN (),erklæret i h header-fil.
  3. Brugerdefineret handlerfunktionsmarkør: Den brugerdefinerede handlerfunktionstype er ugyldig (*) (int), betyder returtype er ugyldig, og et argument af typen int.

Grundlæggende signalhåndteringseksempel

#omfatte
#omfatte
#omfatte
ugyldig sig_handler (int signum)
// Returtypen for handlerfunktionen skal være ugyldig
printf ("\ nIndvendig handlerfunktion \ n");

int main ()
signal (SIGINT, sig_handler); // Registrer signalhåndterer
for (int i = 1 ;; i ++) // Infinite loop
printf ("% d: Inde i hovedfunktionen \ n", i);
søvn (1); // Forsink i 1 sekund

returnere 0;

På skærmbilledet af output fra eksempel 1.c, kan vi se, at i hovedfunktion udføres uendelig løkke. Når brugeren skrev Ctrl + C, stoppes udførelsen af ​​hovedfunktionen og signalets behandlerfunktion. Efter afslutningen af ​​behandlerfunktionen genoptog udførelsen af ​​hovedfunktionen. Når brugertypen er skrevet Ctrl + \, afsluttes processen.

Ignorer eksempler på signaler

#omfatte
#omfatte
#omfatte
int main ()
signal (SIGINT, SIG_IGN); // Registrer signalhåndterer for at ignorere signalet
for (int i = 1 ;; i ++) // Infinite loop
printf ("% d: Inde i hovedfunktionen \ n", i);
søvn (1); // Forsink i 1 sekund

returnere 0;

Her registreres handlerfunktionen til SIG_IGN () funktion til ignorering af signalhandling. Så når brugeren skrev Ctrl + C,  SIGINT signalet genereres, men handlingen ignoreres.

Omregistrer signalhåndteringseksempel

#omfatte
#omfatte
#omfatte
ugyldig sig_handler (int signum)
printf ("\ nIndvendig handlerfunktion \ n");
signal (SIGINT, SIG_DFL); // Registrer signalhåndterer igen for standardhandling

int main ()
signal (SIGINT, sig_handler); // Registrer signalhåndterer
for (int i = 1 ;; i ++) // Infinite loop
printf ("% d: Inde i hovedfunktionen \ n", i);
søvn (1); // Forsink i 1 sekund

returnere 0;

På skærmbilledet af output fra eksempel 3.c, kan vi se, at når brugeren første gang skrev Ctrl + C, påkaldte handlerfunktionen. I behandlerfunktionen registreres signalbehandleren igen til SIG_DFL for signalets standardhandling. Når brugeren skrev Ctrl + C for anden gang, afsluttes processen, hvilket er standardhandlingen for SIGINT signal.

Afsendelse af signaler:

En proces kan også eksplicit sende signaler til sig selv eller til en anden proces. hæve () og dræbe () funktion kan bruges til at sende signaler. Begge funktioner erklæres i signal.h header-fil.

int hæve (int signum)

Funktionen hæve () bruges til at sende signal signum til opkaldsprocessen (sig selv). Det returnerer nul, hvis det lykkes, og en ikke-nul værdi, hvis det mislykkes.

int kill (pid_t pid, int signum)

Drabfunktionen, der bruges til at sende et signal signum til en proces eller procesgruppe, der er specificeret af pid.

SIGUSR1 Signalhåndteringseksempel

#omfatte
#omfatte
ugyldig sig_handler (int signum)
printf ("Inside handler-funktion \ n");

int main ()
signal (SIGUSR1, sig_handler); // Registrer signalhåndterer
printf ("Inde hovedfunktion \ n");
hæve (SIGUSR1);
printf ("Inde hovedfunktion \ n");
returnere 0;

Her sender processen SIGUSR1-signalet til sig selv ved hjælp af funktionen raise ().

Hæv med Kill Example Program

#omfatte
#omfatte
#omfatte
ugyldig sig_handler (int signum)
printf ("Indehåndteringsfunktion \ n");

int main ()
pid_t pid;
signal (SIGUSR1, sig_handler); // Registrer signalhåndterer
printf ("Inde hovedfunktion \ n");
pid = getpid (); // Process-ID for sig selv
dræbe (pid, SIGUSR1); // Send SIGUSR1 til sig selv
printf ("Inde hovedfunktion \ n");
returnere 0;

Her sendes processen SIGUSR1 signal til sig selv ved hjælp af dræbe() fungere. getpid () bruges til at få proces-ID'et af sig selv.

I det næste eksempel vil vi se, hvordan forældre- og barnprocesser kommunikerer (Inter Process Communication) ved hjælp af dræbe() og signalfunktion.

Forældrebørns kommunikation med signaler

#omfatte
#omfatte
#omfatte
#omfatte
ugyldigt sig_handler_parent (int signum)
printf ("Forælder: Modtaget et svarsignal fra barnet \ n");

ugyldigt sig_handler_child (int signum)
printf ("Barn: Modtaget et signal fra forælder \ n");
søvn (1);
dræb (getppid (), SIGUSR1);

int main ()
pid_t pid;
hvis ((pid = gaffel ())<0)
printf ("Gaffel mislykkedes \ n");
udgang (1);

/ * Barneproces * /
ellers hvis (pid == 0)
signal (SIGUSR1, sig_handler_child); // Registrer signalhåndterer
printf ("Barn: venter på signal \ n");
pause();

/ * Forældreproces * /
andet
signal (SIGUSR1, sig_handler_parent); // Registrer signalhåndterer
søvn (1);
printf ("Forælder: sender signal til barn \ n");
dræbe (pid, SIGUSR1);
printf ("Forælder: venter på svar \ n");
pause();

returnere 0;

Her, gaffel() funktion skaber underordnet proces og returnerer nul til underordnet proces og underordnet proces-id til forældreproces. Så pid er blevet kontrolleret for at bestemme forældre- og barneproces. I forældreprocessen soves den i 1 sekund, så underordnet proces kan registrere signalhåndteringsfunktion og vente på signalet fra forælder. Efter 1 sekund forældre proces sende SIGUSR1 signal til barn-processen, og vent på svarets signal fra barnet. I underordnet proces venter det først på signal fra forælder, og når signal modtages, kaldes handlerfunktion. Fra behandlerfunktionen sender barneprocessen en anden SIGUSR1 signal til forælder. Her getppid () funktion bruges til at hente forældreproces-id.

Konklusion

Signal i Linux er et stort emne. I denne artikel har vi set, hvordan man håndterer signal fra det helt grundlæggende, og også får en viden om, hvordan signalet genererer, hvordan en proces kan sende signal til sig selv og anden proces, hvordan signal kan bruges til kommunikation mellem processer.

Mus Sådan ændres mus og touchpad-indstillinger ved hjælp af Xinput i Linux
Sådan ændres mus og touchpad-indstillinger ved hjælp af Xinput i Linux
De fleste Linux-distributioner leveres som standard med "libinput" -biblioteket til at håndtere inputhændelser på et system. Det kan behandle inputhæn...
Mus Remap dine museknapper forskelligt til anden software med X-Mouse Button Control
Remap dine museknapper forskelligt til anden software med X-Mouse Button Control
Måske har du brug for et værktøj, der kan ændre din muses kontrol med hver applikation, du bruger. Hvis dette er tilfældet, kan du prøve en applikatio...
Mus Microsoft Sculpt Touch Wireless Mouse Review
Microsoft Sculpt Touch Wireless Mouse Review
Jeg har for nylig læst om Microsoft Sculpt Touch trådløs mus og besluttede at købe den. Efter at have brugt det et stykke tid besluttede jeg at dele m...