C Programmēšana

Kā lietot signālu apstrādātājus C valodā?

Kā lietot signālu apstrādātājus C valodā?
Šajā rakstā mēs parādīsim, kā izmantot signālu apstrādātājus Linux, izmantojot C valodu. Bet vispirms mēs apspriedīsim, kas ir signāls, kā tas ģenerēs dažus izplatītus signālus, kurus varat izmantot savā programmā, un pēc tam mēs izskatīsim, kā programma var apstrādāt dažādus signālus, kamēr programma. Tātad, sāksim.

Signāls

Signāls ir notikums, kas tiek ģenerēts, lai paziņotu procesam vai pavedienam, ka ir notikusi kāda svarīga situācija. Kad process vai pavediens ir saņēmis signālu, process vai pavediens pārtrauks tā darbību un veiks dažas darbības. Signāls var būt noderīgs saziņai starp procesiem.

Standarta signāli

Signāli ir definēti galvenes failā signāls.h kā makro konstante. Signāla nosaukums ir sācies ar “SIG” un tam seko īss signāla apraksts. Tātad katram signālam ir unikāla skaitliskā vērtība. Programmai vienmēr jāizmanto signālu nosaukums, nevis signālu numurs. Iemesls ir tas, ka signāla numurs var atšķirties atkarībā no sistēmas, bet vārdu nozīme būs standarta.

Makro NSIG ir kopējais definētā signāla skaits. Vērtība NSIG ir par vienu lielāku par kopējo definēto signāla skaitu (visi signālu numuri tiek piešķirti secīgi).

Standarta signāli ir šādi:

Signāla nosaukums Apraksts
SIGHUP Pārtrauciet procesu. SIGHUP signāls tiek izmantots, lai ziņotu par lietotāja termināla atvienošanos, iespējams, tāpēc, ka ir zaudēts vai tiek pārtraukts attālais savienojums.
PARAKSTS Pārtrauciet procesu. Kad lietotājs ievada INTR rakstzīmi (parasti Ctrl + C), tiek nosūtīts SIGINT signāls.
SIGQUIT Iziet no procesa. Kad lietotājs ieraksta QUIT rakstzīmi (parasti Ctrl + \), tiek nosūtīts SIGQUIT signāls.
SIGILL Nelikumīga instrukcija. Mēģinot izpildīt atkritumus vai priviliģētas instrukcijas, tiek ģenerēts SIGILL signāls. Arī SIGILL var ģenerēt, kad kaudze pārplūst vai kad sistēmai ir problēmas palaist signālu apstrādātāju.
SIGTRAP Trace lamatas. Laušanas punkta instrukcija un citas slazdošanas instrukcijas ģenerēs SIGTRAP signālu. Atkļūdotājs izmanto šo signālu.
SIGABRT Pārtraukt. Signāls SIGABRT tiek ģenerēts, kad tiek izsaukta abort () funkcija. Šis signāls norāda uz kļūdu, kuru atklāj pati programma un par kuru ziņo abort () funkcijas izsaukums.
SIGFPE Peldošo punktu izņēmums. Kad radās fatāla aritmētiskā kļūda, tiek ģenerēts SIGFPE signāls.
SIGUSR1 un SIGUSR2 Signālus SIGUSR1 un SIGUSR2 var izmantot pēc vēlēšanās. Viņiem ir lietderīgi ierakstīt signālu apstrādātāju programmā, kas saņem signālu vienkāršai starpprocesu komunikācijai.

Signālu noklusējuma darbība

Katram signālam ir noklusējuma darbība, viena no šīm darbībām:

Jēdziens: Process tiks pārtraukts.
Kodols: Process tiks izbeigts un tiks izveidots kodola dump fails.
Ign: Process ignorēs signālu.
Pietura: Process apstāsies.
Turpinājums: Procesa turpināšana tiks pārtraukta.

Noklusējuma darbību var mainīt, izmantojot apdarinātāja funkciju. Dažu signālu noklusējuma darbību nevar mainīt. SIGKILL un SIGABRT signāla noklusējuma darbību nevar mainīt vai ignorēt.

Signālu apstrāde

Ja process saņem signālu, procesam ir šāda veida signāla darbības izvēle. Process var ignorēt signālu, var norādīt apstrādātāja funkciju vai pieņemt šāda veida signāla noklusējuma darbību.

Mēs varam rīkoties ar signālu, izmantojot signāls vai sigaction funkciju. Šeit mēs redzam, kā vienkāršākais signāls () funkcija tiek izmantota signālu apstrādei.

int signāls () (int signum, void (* func) (int))

The signāls () piezvanīs func funkcija, ja process saņem signālu signum. The signāls () atgriež rādītāju darbībai func ja tas ir veiksmīgs vai tas atgriež kļūdu uz kļūdu un -1 citādi.

The func rādītājam var būt trīs vērtības:

  1. SIG_DFL: Tas ir rādītājs sistēmas noklusējuma funkcijai SIG_DFL (), deklarēts h galvenes fails. To izmanto signāla noklusējuma darbību veikšanai.
  2. SIG_IGN: Tas norāda, ka sistēma ignorē funkciju SIG_IGN (),deklarēts h galvenes fails.
  3. Lietotāja definēts apdarinātāja funkcijas rādītājs: Lietotāja definēts apstrādātāja funkcijas tips ir anulēts (*) (int), nozīmē, ka atgriešanās tips ir nederīgs, un viens argumenta tips ir int.

Signāla apstrādes pamata piemērs

# iekļaut
# iekļaut
# iekļaut
void sig_handler (int signum)
// Apstrādātāja funkcijas atgriešanas tipam jābūt nederīgam
printf ("\ nIespējas apstrādātāja funkcija \ n");

int main ()
signāls (SIGINT, sig_handler); // Reģistrēt signālu apstrādātāju
par (int i = 1 ;; i ++) // Bezgalīgā cilpa
printf ("% d: iekšpusē galvenā funkcija \ n", i);
gulēt (1); // Kavēšanās uz 1 sekundi

atgriešanās 0;

1. piemēra izvades ekrānuzņēmumā.c, mēs varam redzēt, ka galvenajā funkcijā tiek izpildīta bezgalīga cilpa. Kad lietotājs ierakstīja Ctrl + C, galvenās funkcijas izpilde apstājas un tiek izsaukta signāla apstrādātāja funkcija. Pēc apstrādes funkcijas pabeigšanas atsākta galvenās funkcijas izpilde. Kad lietotāja tips ir Ctrl + \, process tiek pārtraukts.

Ignorēt signālu piemēru

# iekļaut
# iekļaut
# iekļaut
int main ()
signāls (SIGINT, SIG_IGN); // Reģistrējiet signāla apstrādātāju signāla ignorēšanai
par (int i = 1 ;; i ++) // Bezgalīgā cilpa
printf ("% d: iekšpusē galvenā funkcija \ n", i);
gulēt (1); // Kavēšanās uz 1 sekundi

atgriešanās 0;

Šeit apstrādātāja funkcija ir reģistrēties SIG_IGN () funkcija signāla darbības ignorēšanai. Tātad, kad lietotājs ierakstīja Ctrl + C,  PARAKSTS signāls tiek ģenerēts, bet darbība tiek ignorēta.

Pārreģistrējiet signālu apstrādātāja piemēru

# iekļaut
# iekļaut
# iekļaut
void sig_handler (int signum)
printf ("\ nIespējas apstrādātāja funkcija \ n");
signāls (SIGINT, SIG_DFL); // Pārreģistrēt signālu apstrādātāju noklusējuma darbībai

int main ()
signāls (SIGINT, sig_handler); // Reģistrēt signālu apstrādātāju
par (int i = 1 ;; i ++) // Bezgalīgā cilpa
printf ("% d: iekšpusē galvenā funkcija \ n", i);
gulēt (1); // Kavēšanās uz 1 sekundi

atgriešanās 0;

3. piemēra izvades ekrānuzņēmumā.c, mēs varam redzēt, ka, kad lietotājs pirmo reizi rakstīja Ctrl + C, tika izsaukta apdarinātāja funkcija. Apstrādātāja funkcijā signālu apstrādātājs pārreģistrējas SIG_DFL signāla noklusējuma darbībai. Kad lietotājs otro reizi ierakstīja Ctrl + C, process tiek pārtraukts, kas ir noklusējuma darbība PARAKSTS signāls.

Signālu sūtīšana:

Process var arī skaidri nosūtīt signālus sev vai citam procesam. signālu sūtīšanai var izmantot funkciju pacelt () un nogalināt (). Abas funkcijas ir deklarētas signālā.h galvenes fails.

int paaugstināt (int signum)

Signāla sūtīšanai izmantotā funkcija pacelt () signum uz izsaukšanas procesu (pats). Ja tas ir veiksmīgs, tas atgriež nulli, ja neizdodas - nulles vērtību.

int kill (pid_t pid, int signum)

Kill funkcija, ko izmanto signāla nosūtīšanai signum uz procesu vai procesu grupu, ko norādījis pid.

SIGUSR1 signālu apstrādātāja piemērs

# iekļaut
# iekļaut
void sig_handler (int signum)
printf ("Iekšējā apdarinātāja funkcija \ n");

int main ()
signāls (SIGUSR1, sig_handler); // Reģistrēt signālu apstrādātāju
printf ("Iekšpusē galvenā funkcija \ n");
paaugstināt (SIGUSR1);
printf ("Iekšpusē galvenā funkcija \ n");
atgriešanās 0;

Šeit process nosūta SIGUSR1 signālu sev, izmantojot funkciju raise ().

Paaugstiniet ar Kill piemēru

# iekļaut
# iekļaut
# iekļaut
void sig_handler (int signum)
printf ("Iekšējā apdarinātāja funkcija \ n");

int main ()
pid_t pid;
signāls (SIGUSR1, sig_handler); // Reģistrēt signālu apstrādātāju
printf ("Iekšpusē galvenā funkcija \ n");
pid = getpid (); // Pats procesa ID
nogalināt (pid, SIGUSR1); // Nosūtiet SIGUSR1 sev
printf ("Iekšpusē galvenā funkcija \ n");
atgriešanās 0;

Lūk, process nosūtīt SIGUSR1 signālu sev, izmantojot nogalināt () funkciju. getpid () tiek izmantots, lai iegūtu procesa ID.

Nākamajā piemērā mēs redzēsim, kā vecāku un bērnu procesi sazinās (starpprocesu komunikācija), izmantojot nogalināt () un signāla funkcija.

Vecāku bērnu saziņa ar signāliem

# iekļaut
# iekļaut
# iekļaut
# iekļaut
void sig_handler_parent (int signum)
printf ("Vecāki: saņēma atbildes signālu no bērna \ n");

void sig_handler_child (int signum)
printf ("Bērns: saņēmis signālu no vecākiem \ n");
gulēt (1);
nogalināt (getppid (), SIGUSR1);

int main ()
pid_t pid;
ja ((pid = dakša ())<0)
printf ("Dakša neizdevās \ n");
izeja (1);

/ * Bērna process * /
cits, ja (pid == 0)
signāls (SIGUSR1, sig_handler_child); // Reģistrēt signālu apstrādātāju
printf ("Bērns: gaida signālu \ n");
pauze ();

/ * Vecāku process * /
cits
signāls (SIGUSR1, sig_handler_parent); // Reģistrēt signālu apstrādātāju
gulēt (1);
printf ("Vecāki: signāla sūtīšana bērnam \ n");
nogalināt (pid, SIGUSR1);
printf ("Vecāki: gaida atbildi \ n");
pauze ();

atgriešanās 0;

Šeit, dakša () funkcija izveido bērna procesu un atgriež nulli bērna procesam un bērna procesa ID vecāku procesam. Tātad, pid ir pārbaudīts, lai izlemtu vecāku un bērnu procesu. Vecāku procesā tas tiek gulēts 1 sekundi, lai bērns varētu reģistrēt signāla apstrādes funkciju un gaidīt signālu no vecākiem. Pēc 1 sekundes vecāku process nosūtīt SIGUSR1 signāls bērnam un gaidiet atbildes signālu no bērna. Bērna procesā vispirms tas gaida signālu no vecākiem un, saņemot signālu, tiek izmantota izsaucēja funkcija. No apstrādātāja funkcijas bērna process nosūta citu SIGUSR1 signāls vecākiem. Šeit getppid () funkcija tiek izmantota, lai iegūtu vecāku procesa ID.

Secinājums

Signāls Linux ir liela tēma. Šajā rakstā mēs esam redzējuši, kā rīkoties ar signālu no pamata, kā arī iegūt zināšanas par signāla ģenerēšanu, kā process var nosūtīt signālu sev un citiem procesiem, kā signālu var izmantot starpprocesu komunikācijai.

Kontrolējiet un pārvaldiet peles kustību starp vairākiem monitoriem sistēmā Windows 10
Dual Display Mouse Manager ļauj kontrolēt un konfigurēt peles kustību starp vairākiem monitoriem, palēninot tās kustību robežas tuvumā. Windows 10/8 ļ...
WinMouse ļauj jums pielāgot un uzlabot peles rādītāja kustību Windows datorā
Ja vēlaties uzlabot peles rādītāja noklusējuma funkcijas, izmantojiet bezmaksas programmatūru WinMouse. Tas pievieno vairāk funkciju, kas palīdzēs jum...
Peles kreisā klikšķa poga nedarbojas operētājsistēmā Windows 10
Ja ar klēpjdatoru vai galddatoru izmantojat īpašu peli, bet nedarbojas peles kreisās klikšķa poga kādu iemeslu dēļ operētājsistēmā Windows 10/8/7 šeit...