Inhoud serie:
In moderne besturingssystemen is er het concept van Inter-Process Communication (IPC) - een reeks methoden voor het uitwisselen van gegevens tussen processen en/of threads. Signalen zijn een van deze uitwisselingsmethoden. Het signaalconcept wordt door de meeste besturingssystemen ondersteund, maar bijvoorbeeld Windows niet. volledige ondersteuning voor gebruik als een van de IPC-methoden - in dergelijke besturingssystemen worden signalen alleen geïmplementeerd in de standaard C-bibliotheek.
Signaalconcept
Signalen zijn in staat tot: willekeurige tijd(asynchroon) een proces onderbreken om een gebeurtenis af te handelen. Een proces kan worden onderbroken door een signaal dat is geïnitieerd door een ander proces of een andere kernel. De kernel gebruikt signalen om processen op de hoogte te stellen van verschillende gebeurtenissen, zoals de beëindiging van een onderliggend proces.
Signalen hebben een specifieke levenscyclus. Eerst wordt een signaal gegenereerd - verzonden door een proces of gegenereerd door de kernel. Het signaal wacht vervolgens op levering aan het bestemmingsproces. Algemeen wordt aangenomen dat de wachttijd voor een signaal gelijk is aan het tijdsinterval tussen het aanmaken van een signaal en de actie die dit signaal uitzendt. Uiteindelijk levenscyclus het signaal wordt onderschept (ontvangen) door het proces en de acties die bij het signaal horen worden uitgevoerd.
Eenvoudige signalen en betrouwbare signalen
Er is een verdeling van signalen in eenvoudig en betrouwbaar.
Aanvankelijk werden eenvoudige (onbetrouwbare) signalen ontwikkeld en gebruikt. In hun werkingsprincipe zijn ze vergelijkbaar met het canonieke mechanisme voor het afhandelen van hardware-interrupts in de processor. Als een proces een bepaald signaal op een speciale manier wil verwerken, dan informeert het de kernel hierover en geeft aan: speciale functie- signaalbehandelaar. Bij het afgeven van een signaal aan een proces roept de kernel de signaalbehandelaar zo snel mogelijk aan, waardoor het proces wordt onderbroken. Wanneer de handler klaar is, gaat het proces verder waar het was gebleven.
In plaats van je eigen handlerfunctie te schrijven, kun je de kernel eenvoudig vertellen dat het signaal de standaardactie ervoor aanroept, of dat het signaal gewoon wordt genegeerd.
Dit hele concept van het werken met signalen ziet er goed genoeg uit totdat het signaal arriveert op een moment dat het al bezig is met het verwerken van een ander signaal. Dit is waar het probleem zich voordoet - een opnieuw aangeroepen signaalhandler kan die gedeelde bronnen verknoeien ( algemene structuren gegevens en variabelen) die het gebruikt. Bovendien, in het geval van de aankomst een groot aantal signalen kan de processtack oneindig groeien, wat kan leiden tot programmastoringen.
Bij het oplossen van het probleem zijn betrouwbare signalen ontwikkeld, die in POSIX zijn gestandaardiseerd en tot op de dag van vandaag worden gebruikt. De rest van het artikel richt zich op betrouwbare signalen.
Signalen en systeemoproepen
Een signaal kan naar een proces komen op een moment dat het proces zich in een systeemaanroep bevindt, bijvoorbeeld wachtend tot gegevens worden ingevoerd in read (). In dit geval kan de ontwikkeling van gebeurtenissen het volgende pad volgen: de toepassing probeert het signaal niet te onderscheppen en wordt onderbroken door de kernel (bijvoorbeeld de aankomst van het SIGTERM-signaal) - dan blijft de terminal in een niet-standaard configuratie, die het werk van de gebruiker kan belemmeren. Natuurlijk kunt u het signaal onderscheppen, de terminal wissen in de signaalhandler en vervolgens afsluiten, maar het is vrij moeilijk om een signaalhandler te schrijven die weet wat het programma aan het doen was op het moment van onderbreking om te beslissen of u het wilt wissen de terminal of niet.
Op dit moment is er een signaalimplementatie die vrij is van deze tekortkomingen. De oplossing is om een vlag in de signaalhandler in te stellen om aan te geven dat het signaal is ontvangen en er vervolgens voor te zorgen dat de systeemoproep terugkeert met een foutcode die aangeeft dat de oproep door het signaal werd onderbroken. Vervolgens moet het programma de vlag controleren die is ingesteld door de signaalhandler en uitvoeren: gepaste actie bijvoorbeeld de terminal leegmaken en verlaten.
Moderne signaalimplementatie dwingt traag systeemoproepen een EINTR-foutcode retourneren wanneer onderbroken door een inkomend signaal. Snelle systeemoproepen moeten voltooid zijn voordat het signaal wordt afgegeven. Langzame systeemoproep - Een systeemoproep waarvoor: onbepaald bedrag tijd om te voltooien, bijvoorbeeld lezen (), wachten (), schrijven (). Alle systeemaanroepen die afhankelijk zijn van onvoorspelbare bronnen, zoals menselijke acties, netwerkgegevens en dergelijke, zijn traag. Uiteraard zijn alle andere systeemoproepen snel.
Normaal gesproken verwerkt het programma de EINTR-foutcode en als er niets fataals is gebeurd, wordt de systeemaanroep opnieuw gestart. De meeste Unix-achtige besturingssystemen doen dit momenteel standaard - het enige wat u hoeft te doen is het signaal in de handler afhandelen en de systeemaanroep wordt automatisch opnieuw gestart. In Linux worden systeemaanroepen standaard niet opnieuw gestart, maar voor elk signaal kan een proces een vlag instellen om het systeem te instrueren om langzame systeemaanroepen die door dit signaal worden onderbroken, opnieuw op te starten.
Signalen verzenden
Het verzenden van signalen van het ene proces naar het andere gebeurt meestal met behulp van de systeemaanroep kill (). De eerste parameter is de PID van het proces waarnaar het signaal wordt verzonden; de tweede parameter is het signaalnummer. Als we een SIGTERM-signaal naar een proces met PID 6666 willen sturen, gebruiken we de systeemaanroep kill () als volgt:
doden (6666, SIGTERM);In plaats van positief PID-waarden je kunt de oproep gelijk doorgeven in modulus, maar negatieve betekenis... Vervolgens wordt het signaal naar alle processen uit de groep gestuurd met een nummer gelijk aan de module van de verzonden PID "a. Als PID 0 is, dan wordt het signaal verzonden naar alle processen uit de groep waartoe het huidige proces behoort. Deze mogelijkheden worden voornamelijk gebruikt door shells om taken te controleren.
Als u -1 doorgeeft als de PID voor de kill ()-systeemaanroep, wordt het signaal naar alle processen gestuurd, behalve init "a. Deze functie wordt gebruikt om het systeem af te sluiten.
Meer gedetailleerde informatie voor de kill () systeemaanroep, zie man 2 kill.
Een proces kan een signaal naar zichzelf sturen met behulp van de systeemaanroep raise () waarvoor één parameter nodig is: het signaalnummer. Voorbeeld:
verhogen (SIGTERM);Natuurlijk retourneert elk van de beschouwde systeemaanroepen nul als deze succesvol is en niet nul als er een fout optreedt.
Onderschepping van signalen
Alle POSIX-compatibele programma's registreren hun signaalbehandelaars met de sigaction () systeemaanroep. Deze systeemaanroep heeft drie parameters: de eerste is int signum, het nummer van het onderschepte signaal. De tweede, struct sigaction * act, is een verwijzing naar een structuur die de regels beschrijft voor het instellen van de handler. De derde parameter - struct sigaction * oact - duurt al vastgestelde regels signaal behandelaar. De tweede of de derde (maar niet beide!) Parameter kan indien nodig op NULL worden gezet.
De structuursignalering heeft de volgende beschrijving:
sigactie structureren (__sighandler_t sa_handler; sigset_t sa_mask; int sa_flags;);sa_handler is een pointer naar een signaalhandler en de handler moet als volgt worden gedeclareerd:
void signal_handler (int signo);waarbij de enige parameter het nummer is van het signaal dat in de handler is binnengekomen. sa_handler kan ook SIG_IGN zijn — het signaal wordt genegeerd door het proces, en SIG_DFL — het signaal activeert een standaardactie, zoals het afbreken van het proces.
sa_mask - een reeks signalen die moeten worden geblokkeerd bij het aanroepen van een signaalbehandelaar die in dezelfde structuur is gespecificeerd. Hoe u ze installeert, wordt hieronder besproken.
Met de parameter sa_flags kan een proces het gedrag van het signaal wijzigen. De parameter kan slechts vier waarden aannemen, die echter kunnen worden gecombineerd met de bitsgewijze OF-bewerking:
- SA_NOCLDSTOP - stuur SIGCHLD-signaal alleen als het onderliggende proces wordt onderbroken. Het opschorten van een onderliggend proces leidt niet tot het verzenden van een signaal.
- SA_NODEFER - emulatie van eenvoudige (onbetrouwbare) signalen.
- SA_RESTHAND - nadat een signaal arriveert, wordt de handler teruggezet naar SIG_DFL.
- SA_RESTART - Start de systeemaanroep opnieuw nadat u bent teruggekeerd van de signaalhandler. Als de vlag niet is ingesteld, retourneert de systeemaanroep de fout EINTR.
Zoals gebruikelijk retourneert sigaction () 0 bij succes en een negatieve waarde bij fout.
Proces signaal masker
Signalen toevoegen aan de sigset_t sa_mask-structuur, wissen, enz. worden uitgevoerd met behulp van de reeks functies sigemptyset (), sigfillset (), sigaddset (), sigdelset (). De eerste twee functies hebben één parameter nodig, een verwijzing naar de sigset_t-structuur. Deze functies zijn duidelijk en vullen met iedereen mogelijke signalen respectievelijk de sigset_t-structuur.
De laatste twee functies voegen respectievelijk één specifiek signaal toe aan en verwijderen uit de structuur en hebben twee parameters. Hun eerste parameter is een verwijzing naar de sigset_t-structuur en de tweede is het signaalnummer.
Alle bovenstaande functies retourneren 0 bij succes en een getal dat niet nul is bij fout.
Daarnaast is er nog een functie die controleert of het gespecificeerde signaal zich in de gespecificeerde set bevindt - sigismember (). De parameters zijn dezelfde als die voor sigaddset (). De functie retourneert 1 als het signaal in de set is, 0 als dat niet het geval is, en negatief nummer- wanneer er een fout optreedt.
We kunnen onder andere een lijst met signalen specificeren waarvan de levering aan het proces wordt geblokkeerd. Dit wordt gedaan met behulp van de sigprocmask (int how, const sigset_t * set, sigset_t * oldset) functie.
De eerste parameter beschrijft wat er moet gebeuren:
- SIG_BLOCK - signalen van de set worden geblokkeerd;
- SIG_UNBLOCK - signalen van de set worden gedeblokkeerd;
- SIG_SETMASK - signalen van de set worden geblokkeerd, de rest is gedeblokkeerd.
De tweede parameter is een verwijzing naar dezelfde set van waaruit signalen worden geblokkeerd / gedeblokkeerd. Als het NULL is, wordt de waarde van de eerste parameter genegeerd door de systeemaanroep.
De derde parameter is een verwijzing naar een reeds gebruikt signaalmasker; het kan worden ingesteld op NULL als deze gegevens niet nodig zijn.
Om een lijst met wachtende signalen te krijgen, kunt u de functie sigpending () gebruiken, die een enkele parameter nodig heeft - een verwijzing naar de sigset_t-structuur, waar een reeks wachtende signalen zal worden geschreven.
Principes van het schrijven van signaalhandlers
Een van de belangrijkste regels voor het schrijven van signaalbehandelaars is dat de behandelaar re-entry moet zijn, d.w.z. het moet opnieuw kunnen worden aangeroepen als het proces zich al in de handler bevindt. Er moet voor worden gezorgd dat de signaalbehandelaar geen globale datastructuren of langzame systeemaanroepen gebruikt. Als het helaas onmogelijk is om dit te vermijden, dan loont het de moeite om te zorgen voor bescherming tegen herhaalde oproep van de handler tijdens het werken met een datastructuur of met een systeemaanroep. Dit kan worden bereikt door de levering van het signaal waarvan de handler momenteel actief is tijdelijk te blokkeren met behulp van de systeemaanroep sigprocmask (). We hebben bijvoorbeeld een handler SIGCHLD-signaal, we vergrendelen het als volgt:
void chld_handler (int signum) (sigset_t set; if (sigemptyset (& set)) (return;) if (sigaddset (& set, SIGCHLD)) (return;) if (sigprocmask (SIG_BLOCK, & set, NULL)) (return ;) / * hier iets belangrijks doen * / if (sigprocmask (SIG_UNBLOCK, & set, NULL)) (return;) return;)Naast al het bovenstaande, wordt aangenomen dat de handler zo eenvoudig mogelijk moet zijn - idealiter zou deze een bepaalde vlag moeten instellen en eindigen, en de rest van het programma zou de rest moeten doen.
Gevolgtrekking
Het bovenstaande materiaal is de basis voor het begrijpen van het concept van signalen. Kortom, het zou voldoende moeten zijn voor u om te gaan werken met signalen in uw programma's.
Aan het einde van de cyclus leert u hoe u aanvullende gegevens over een signaal kunt ontvangen (en verzenden) als u de gebruikelijke informatie mist dat een signaal ergens in uw proces vandaan komt.
Bronnen downloaden
static.content.url = http: //www.site/developerworks/js/artrating/
Artikel-ID = 495997
ArticleTitle = Werken met signalen op Linux, deel 1: Basisprincipes van signalering
Signalen zijn softwareonderbrekingen. Ze worden gebruikt voor communicatie tussen processen in UNIX en UNIX-achtige besturingssystemen zoals Linux, Mac OS.
Signalen bestaan al sinds Bell Labs UNIX in 1970 en worden nu officieel gedefinieerd door de POSIX-standaard. Wanneer een signaal bij een proces aankomt, besturingssysteem onderbreekt de normale stroom van een proces en geeft een melding.
Het maakt niet uit welk besturingssysteem u gebruikt, u zult zeker tegenkomen dat uw toepassingen worden geblokkeerd en weigeren goed te werken. In Unix, Linux, is er een "kill"-commando dat je kunt gebruiken om een proces onmiddellijk te beëindigen, maar niet alleen dat, maar daar zal ik het later nog over hebben. In dit artikel "Het kill-commando op Unix / Linux" zal ik uitleggen en laten zien op kant-en-klare voorbeelden verschillende kill-hulpprogramma's.
Commando's en signalen doden
Wanneer u het "kill"-commando uitvoert, stuurt u het in feite een signaal naar het systeem en instrueert u het om de ongeldige robottoepassing te beëindigen. Er zijn in totaal 60 signalen die kunnen worden gebruikt, maar het enige dat u echt moet weten, zijn SIGTERM (15) en SIGKILL (9).
U kunt alle seinen bekijken met het commando:
# kill -l
Op mijn macOS:
Ik zal proberen om over alle signalen te praten, maar laten we om te beginnen alleen de belangrijkste en meest gebruikte signalen bespreken.
Basissignalen
De volgende signalen maken deel uit van de POSIX-standaard. Elk signaal is een macro gedefinieerd in
SIGTERM- Dit signaal vraagt om het lopende proces te stoppen. Dit signaal kan genegeerd worden, het proces krijgt de tijd om goed af te sluiten. Wanneer een programma goed afsluit, betekent dit dat het tijd heeft gekregen om de voortgang op te slaan en middelen vrij te maken. Met andere woorden, het is niet "gedwongen" om het proces te beëindigen.
SIGKILL- het SIGKILL-signaal zorgt ervoor dat het proces zijn werk onmiddellijk beëindigt. Het programma kan dit signaal niet negeren. Niet-opgeslagen voortgang gaat verloren.
Syntaxis voor "doden".
De opdrachtsyntaxis is als volgt:
# kill PID('s)
# kill [-s] [-l]% pid
Het standaardsignaal (indien niet gespecificeerd) is SIGTERM. Wanneer dit signaal niet helpt en niet werkt, kunt u de volgende opties voor "kill" gebruiken om het proces geforceerd te beëindigen:
# dood SIGKILL PID
# kill -9 PID
waarbij "-9" de vlag is, verwijst naar het SIGKILL-signaal.
Als u niet weet welke PID van de toepassing u moet gebruiken om zich te ontdoen van, voer dan de opdracht uit:
$ ps -aux
En als je het weet? specifieke toepassing:(bijvoorbeeld apache), dan kunt u het onnodige verwijderen en alle processen voor deze service weergeven:
$ ps -aux | grep apache
En dit zal alles weergeven actieve applicaties samen met zijn PID('s).
Om de toepassing bijvoorbeeld te doden, voer ik de volgende opdracht uit:
# kill -9 3629
Het is ook vermeldenswaard dat u meerdere processen tegelijkertijd kunt gebruiken, zodat ze kunnen worden "gedood":
# kill -9 PID1 PID2 PID 3
Herlaad configuratiebestanden of herstart hulpprogramma's:
# kill -1 number_of_PID
Bijzonder bruikbare signalen zijn HUP, INT, kill, STOP, CONT en 0.
De opties zijn als volgt:
-s signaalnaam
Een symbolische signaalnaam die een signaal specificeert voor het verzenden van een niet-standaardsignaal.
-l
Als de operand niet is gespecificeerd, toon dan de namen van de signalen; V anders, schrijf de naam van het signaal dat overeenkomt met exit_status.
-signaalnaam
De symbolische naam van het signaal dat het signaal specificeert dat standaard naar TERM moet worden verzonden.
-signaal_nummer
Een niet-negatief decimaal geheel getal dat het signaal specificeert dat standaard naar TERM moet worden verzonden.
De volgende PID's zijn van bijzonder belang:
-1
Als de superuser een signaal uitzendt naar alle processen; anders behoren uitzendingen tot alle processen-
voor de gebruiker.
Enkele van de meest gebruikte signalen:
- 1 HUP (ophangen) - ophangen.
- 2 INT (onderbreken) - onderbreken.
- 3 STOP (stop) - afsluiten.
- 6 ABRT (afbreken) - onderbrekingen.
- 9 DODEN (niet vangbare, niet te negeren kill)
- 14 ALRM ( wekker) - alarm.
- 15 TERM (softwarebeëindigingssignaal) - Software voor het beëindigen van het signaal.
PKill
Met de opdracht pkill kunt u geavanceerde patronen van reguliere expressies en andere overeenkomende criteria gebruiken. In plaats van de PID te gebruiken, kunt u de toepassing nu beëindigen door de procesnaam in te voeren. Om bijvoorbeeld de Firefox-browser te beëindigen, voert u eenvoudig de opdracht uit:
# pkill Firefox
Omdat het overeenkomt met het patroon reguliere expressie, kunt u ook een deel van de procesnaam invoeren, bijvoorbeeld:
# pkill vuur
Om te voorkomen dat de verkeerde processen worden afgebroken, kunt u "pgrep -l [procesnaam]" doen in de lijst met in aanmerking komende processen.
Het pkill-commando heeft veel meer opties, bijvoorbeeld als u de optie "-u" specificeert, kunt u een gebruikersnaam of ID opgeven. In dit voorbeeld sturen we het TERM-signaal naar alle processen die eigendom zijn van de gebruiker 'niemand':
# pkill -u niemand
Killall
Killall gebruikt de procesnaam in plaats van de PID, en het "doodt" alle instanties van het proces met dezelfde naam. Als u bijvoorbeeld meerdere instanties gebruikt Firefox-browser, je kunt ze allemaal doden met het commando:
# killall firefox
In Gnome kun je Nautilus opnieuw opstarten met de opdracht:
# killall nautilus
xkill
Xkill is grafisch"Dood" de applicatie. Wanneer u "XKill" invoert in de terminal, wordt de muiscursor onmiddellijk "kruis". Het enige wat u hoeft te doen is op het "kruisje" op de gewraakte applicatie te drukken en het zal de applicatie onmiddellijk doden. Als u geïnteresseerd bent, kunt u een sneltoets toevoegen om de XKill-functie in te schakelen.
Meer signalen die worden gebruikt
SIGABRT
Dit signaal stuurt een signaal naar het proces om de bewerking af te breken. ABRT is meestal gericht op het proces zelf wanneer het de functie abort () van de programmeertaal C aanroept om te signaleren abnormale beëindiging maar het kan net als elk ander signaal vanuit elk proces worden verzonden.
SIGALRM, SIGVTALRM en SIGPROF
ALRM, VTALRM en/of PROF wordt naar een proces gestuurd wanneer de opgegeven tijdslimiet bij het aanroepen van een alarmfunctie (zoals setitimer) verloopt.
ALRM
Verzonden wanneer aanwezig of klok over tijd is.
VTALRM
Wordt verzonden wanneer de processortijd die door het proces wordt gebruikt, is verstreken.
PROF
Wordt verzonden wanneer de processortijd die door het proces en het systeem namens het proces wordt gebruikt, is verstreken.
SIGBUS
Er wordt een BUS-signaal naar een proces gestuurd wanneer dit resulteert in een busfout. Omstandigheden die tot dit signaal leiden, zoals verkeerd uitgelijnde geheugentoegang of ontbrekend fysiek adres.
SIGCHLD
Het CHLD-signaal wordt naar een proces gestuurd wanneer een onderliggend proces wordt beëindigd, onderbroken of hervat na een onderbreking. Een veelgebruikt gebruik van het signaal is om het besturingssysteem te signaleren om bronnen op te schonen die door het onderliggende proces worden gebruikt nadat het is beëindigd zonder een expliciete systeemaanroep.
SIGCONT
Het CONT-signaal instrueert het besturingssysteem en geeft aan om een proces opnieuw te starten dat eerder was onderbroken in de STOP- of TSTP-modus. Een van de belangrijke mogelijkheden dit signaal is om het werk in de Unix-shell te controleren.
SIGFPE
Het FPE-signaal wordt naar een proces gestuurd wanneer het foutieve rekenkundige bewerkingen uitvoert, zoals delen door nul.
SIGHUP
Het HUP-signaal wordt naar een proces gestuurd wanneer de bedieningsterminal is gesloten. Het was oorspronkelijk ontworpen om een proces op de hoogte te stellen na een opeenvolgende regeldaling (HUP is verantwoordelijk voor "hangt"). In moderne systemen betekent dit signaal meestal dat de besturing van de pseudo- of virtuele terminal is gesloten.
SIGILL
IBL-signaal dat naar een proces wordt gestuurd wanneer het kwaadwillende, onbekende of geprivilegieerde opdrachten (instructies) probeert uit te voeren.
SIGINT
Een INT-signaal wordt vanaf de besturingsterminal naar een proces gestuurd wanneer de gebruiker het proces wil afbreken. Dit wordt meestal gestart door op Control-C te drukken, maar op sommige systemen, "delete" of "break".
SIGKILL
Het KILL-signaal wordt naar het proces gestuurd om het onmiddellijk te doden. In tegenstelling tot SIGTERM en SIGINT kan dit signaal niet worden opgevangen of genegeerd, en het ontvangende proces kan geen opschoning uitvoeren na ontvangst van dit signaal.
SIGPIPE
Het PIPE-signaal wordt naar een proces gestuurd wanneer het probeert te schrijven naar een pijp zonder dat er aan het andere uiteinde een proces is aangesloten.
SIGQUIT
Een QUIT-signaal wordt naar een proces gestuurd vanaf de besturingsterminal wanneer de gebruiker een dumpproces aanvraagt.
SIGSEGV
Een SEGV-signaal wordt naar een proces gestuurd wanneer het een ongeldige link maakt virtueel geheugen of een segmentatiefout, dat wil zeggen, wanneer het een segmentatieschending uitvoert.
SIGSTOP
Het STOP-signaal vertelt het besturingssysteem om het proces te stoppen voor latere hervatting.
SIGTERM
Het TERM-signaal wordt naar het proces gestuurd om beëindiging aan te vragen. In tegenstelling tot het kill-signaal kan het tijdens het proces worden geïnterpreteerd of genegeerd. Hierdoor kan het proces een "mooie" uitvoering uitvoeren om het vrijgeven van bronnen te stoppen en de status op te slaan wanneer dat nodig is. Opgemerkt moet worden dat SIGINT bijna identiek is aan SIGTERM.
SIGTSTP
Een TSTP-signaal wordt naar het controlerende terminalproces gestuurd en vertelt het tijdelijk te onderbreken. Dit wordt meestal door de gebruiker geïnitieerd door op Control-Z te drukken. In tegenstelling tot SIGSTOP kan dit proces een signaalbehandelaar registreren of het signaal negeren.
SIGTTIN en SIGTTOU
In TTIN en TTOU worden signalen naar een proces gestuurd wanneer het respectievelijk probeert te lezen of te schrijven vanaf een (tty) terminal op de achtergrond. Dit signaal kan doorgaans alleen worden ontvangen door processen die onder controle zijn. werkpaneel; daemons hebben geen controleterminals en zouden dit signaal nooit mogen ontvangen.
SIGUSR1 en SIGUSR2
USR1- en USR2-signalen worden naar het proces gestuurd en geven door de gebruiker gedefinieerde voorwaarden aan.
SIGPOLL
Het POLL-signaal wordt verzonden in een proces wanneer een asynchrone I / O-gebeurtenis optreedt.
SIGSYS
Het SYS-signaal wordt verzonden in een proces wanneer het een slecht argument voor een systeemaanroep mist.
SIGTRAP
Er wordt een TRAP-signaal naar een proces gestuurd wanneer zich een voorwaarde voordoet die de debugger heeft gevraagd te worden geïnformeerd, bijvoorbeeld wanneer: specifieke functie wordt uitgevoerd of wanneer een specifieke waarde van een variabele verandert.
SIGURG
Een URG-signaal wordt naar een proces gestuurd wanneer de socket dringende of buiten bereikgegevens beschikbaar heeft om te lezen.
SIGXCPU
Het XCPU-signaal wordt tijdens het proces verzonden wanneer het wordt gebruikt CPU voor een tijd die een bepaalde vooraf ingestelde waarde overschrijdt, ingesteld door de gebruiker... De komst van het XCPU-signaal zorgt ervoor dat het proces snel alles opslaat tussentijdse resultaten en het wordt afgesloten ruim voordat het het besturingssysteem verlaat met het SIGKILL-signaal.
SIGXFSZ
Het XFSZ-signaal wordt verzonden wanneer het bestand groter wordt (de opgegeven waarde overschrijdt) dan de maximaal toegestane waarde.
SIGRTMIN naar SIGRTMAX
RTMIN - RTMAX-signalen zijn voor aangepast gebruik. Het zijn realtime signalen.
Verschillende signalen
De volgende signalen zijn niet gestandaardiseerd door POSIX, maar worden soms op sommige systemen gebruikt.
SIGEMT
Het EMT-signaal wordt tijdens het proces verzonden wanneer een emulatoronderbreking optreedt.
SIGINFO
Het INFO-signaal wordt verzonden wanneer een statusverzoek van de controlerende terminal wordt ontvangen.
SIGPWR
Het PWR-signaal wordt verzonden wanneer het systeem een stroomstoring ondervindt.
SIGLOST
Een LOST-signaal wordt naar een proces gestuurd wanneer de bestandsvergrendeling verloren is gegaan.
SIGWINCH
Het WINCH-signaal wordt verzonden in een proces wanneer de bedieningsterminal van grootte verandert.
Signalen verzenden vanaf het toetsenbord
Signalen kunnen vanaf het toetsenbord worden verzonden. Hieronder vindt u een aantal standaardinstellingen. De standaard sneltoetsen voor het verzenden van interruptsignalen kunnen worden gedefinieerd met het stty-commando.
CTRL-C
SIGINT verzenden (onderbreken). Standaard wordt hierdoor het proces beëindigd.
CTRL-Z
SIGTSTP verzenden (opschorten). Standaard zorgt dit ervoor dat het proces alle bewerkingen opschort.
CTRL- \
SIGQUIT verzenden (Sluiten). Dit zorgt er standaard voor dat het proces onmiddellijk wordt beëindigd en de kernel wordt gereset.
CTRL-T
Stuur SIGINFO (INFO). Standaard dwingt dit het besturingssysteem om informatie over de opdracht weer te geven. Niet ondersteund op alle systemen.
gevolgtrekking
Wanneer toepassingen zich misdragen en ervoor zorgen dat het systeem vastloopt, is het erg verleidelijk om de computer opnieuw op te starten en de sessie steeds opnieuw te starten. Met deze "kill"-commando's kunt u slecht gedrag van toepassingen die systeemcrashes veroorzaken of kunnen veroorzaken, beter beheren. Dit concludeert: dit onderwerp"Het kill-commando op Unix / Linux."
Signalen zijn interruptverzoeken die op procesniveau worden geïmplementeerd. Gedefinieerd meer dan dertig verschillende signalen en ze vinden een breed scala aan toepassingen.
- Als communicatiemiddel kunnen signalen tussen processen worden verzonden.
- Signalen kunnen door het terminalstuurprogramma worden verzonden om processen te beëindigen of op te schorten wanneer de gebruiker op . drukt speciale combinaties toetsen zoals
of . - Signalen kunnen voor verschillende doeleinden worden verzonden door een gebruiker of een beheerder met behulp van het kill-commando.
- Signalen kunnen door de kernel worden verzonden wanneer een proces een illegale instructie uitvoert, zoals delen door nul.
- Signalen kunnen door de kernel worden verzonden om een proces op de hoogte te stellen van een "interessante" gebeurtenis, zoals de beëindiging van een onderliggend proces of de beschikbaarheid van gegevens op een I/O-pipe.
- Een geheugendump is een bestand dat een geheugenafbeelding van een proces bevat. Het kan worden gebruikt voor debuggen.
- Het KILL-signaal blokkeert niet en zorgt ervoor dat het proces onvoorwaardelijk wordt beëindigd op kernelniveau. In feite heeft het proces niet eens tijd om dit signaal te ontvangen.
- INT-signaal wordt verzonden door de terminaldriver wanneer de gebruiker op een toetscombinatie drukt
en dient als een verzoek om de huidige bewerking te voltooien. Door dit signaal op te vangen, moeten eenvoudige programma's afsluiten, of de standaard signaalbehandelaar zichzelf laten vernietigen. Programma's met een interactieve opdrachtregel moeten de huidige bewerking afbreken, opschonen en teruggaan naar stand-by. - Het TERM-signaal is een verzoek om het programma te beëindigen. Het proces dat dit signaal ontvangt, zal naar verwachting opschonen en afsluiten.
- Het HUP-signaal heeft twee gemeenschappelijke interpretaties. Ten eerste behandelen veel demonen het als een reset-opdracht. Als de demon in staat is zijn eer opnieuw te verkondigen config-bestand en aan te passen aan veranderingen zonder opnieuw te starten, laat het HUP-signaal zijn gedrag veranderen.
- Ten tweede wordt dit signaal soms gegenereerd door het terminalstuurprogramma wanneer het probeert terminalgerelateerde processen te beëindigen. Kortom, dit gedrag is bewaard gebleven vanaf de dagen van gebruik. bedrade verbindingen terminals en modems. Vandaar de naam "ophangen".
- De tolken van de csh-familie (tcsh en anderen) doen dat meestal: achtergrondprocessen immuun voor het HUP-signaal, zodat ze hun werk kunnen voortzetten, zelfs als de gebruiker is uitgelogd. Gebruikers van de sh-familie van tolken (ksh, bash, enz.) kunnen dit gedrag nabootsen met het nohup-commando.
- Het QUIT-signaal is vergelijkbaar met het TERM-signaal, behalve dat de standaardhandler standaard een geheugendump maakt.
Veel Unix-programma's accepteren signalen zoals USR1 en USR2. Om bijvoorbeeld te updaten uitvoerbaar bestand voor nginx on the fly stuur je kill -USR2.
Ik begrijp dat USR1 een "door de gebruiker gedefinieerd" signaal is, wat betekent dat degene die het programma heeft gemaakt het kan gebruiken om "afsluiten" of "uw logs dumpen" of "duizend keer afdrukken" of wat dan ook te betekenen. Maar ik begrijp niet waarom ze deze willekeurige naam zouden moeten gebruiken. Waarom niet -UPGRADE doden, of -GRACEFUL_SHUTDOWN doden? Heeft Unix alleen bepaalde signalen?
Terwijl we dit doen, gebruikt Nginx ook de volgende signalen (zie documentatie):
- TERMIJN, INT: snel afsluiten
- ONTSLAG NEMEN: sierlijk afsluiten
- HUP:
- Configuratie opnieuw opstarten
- Start nieuwe workflows met nieuwe configuratie
- Sierlijke afsluiting van oude workflows
- USR1: logbestanden openen
- USR2: uitvoerbare bestanden direct bijwerken
- LIER: sierlijke voltooiing van workflows
HUP? Lier? Wat is de reden voor deze namen? Waar kan ik hier meer over te weten komen?
6 antwoorden
De signalen die beschikbaar zijn in het besturingssysteem worden bepaald door het besturingssysteem (meestal na POSIX) - het zijn geen "strings" maar integer-constanten met standaard namen... USR1 en USR2 zijn twee signalen die geen specifieke betekenis hebben, bedoeld voor willekeurig gebruik dat een ontwikkelaar wil.
Op je linux-machine lees man 7 sein voor een overzicht van sein en seinafhandeling.
U kunt de betekenis van andere signalen negeren als u bereid bent om met het besturingssysteem te werken door deze signalen af te geven als reactie op gebeurtenissen. U kunt HUP bijvoorbeeld laten staan voor "reload configuration" - als u zeker weet dat het proces nooit zal vastlopen (terminal loss), of als u bereid bent gevallen aan te pakken waarin het besturingssysteem, niet de gebruiker, het HUP-signaal verzendt.
HUP is niet geschikt om in te vriezen. Dit signaal wordt naar een proces gestuurd als zijn controlerende terminal het einde van het bestand bereikt. Vroeger werden bedieningsterminals meestal aangesloten op: seriële poorten eventueel via een modemlijn op telefoonlijn... Als de telefoonverbinding is omgekeerd, lokale modem zal de Carrier Detect-regel verlagen, die een voltooiingsrapport van het kernelbestand zal verzenden en verzonden signaal INSCHRIJVEN.
WINCH is niet geschikt voor het "veranderen van het raam". Het wordt naar een proces gestuurd als het formaat van de controlerende terminal wordt gewijzigd. Om voor de hand liggende redenen zijn terminals waarvan het formaat kan worden gewijzigd meestal pseudo-terminals, die uiteindelijk worden weergegeven door een terminalemulator die in een vensteromgeving draait (zoals xterm).
Omdat signaalnamen gestandaardiseerd zijn (POSIX). Je kunt je eigen uitvoerbare bestand van het kill-type schrijven om -UPGRADE te nemen als je wilt en het USR1-signaal af te geven, maar de standaard kill die bij UNIX wordt geleverd, herkent het niet.
Als alternatief kunt u een alias, functie of shellscript maken om de vertaling voor u te doen, bijvoorbeeld met een bash-alias:
Alias-upgrade = "kill -USR1"
Het headerbestand signal.h wijst signaalnamen toe aan hun daadwerkelijke implementatieafhankelijke waarden.
In WINCH-termen vind ik dit een beetje afschuwelijk. Dit is het signaal dat aan toepassingen wordt geleverd wanneer het formaat van het venster wordt gewijzigd (vooral wanneer hun controlerende terminalvenster verandert).
Dit gebruiken om werkthreads netjes te sluiten is geen goed idee, tenzij u kunt garanderen dat het proces nooit in de terminal zal worden uitgevoerd. Ik weet dat het een mythe zou zijn als ik de applicatie zou draaien en zou besluiten om al het werk tijdens de vlucht te annuleren alleen maar omdat ik het venster heb gemaximaliseerd :-)
Probeer kill -l en vind zelf het antwoord:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIG 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR) 31) SIGTM 35 + SIGRTM 1 36) SIGRTMIN + 2 37) SIGRTMIN + 3 38) SIGRTMIN + 4 39) SIGRTMIN + 5 40) SIGRTMIN + 6 41) SIGRTMIN + 7 42) SIGRTMIN + 8 43) SIGRTMIN + 9 44) SIGRTMIN + 10 45) SIGRTMIN + 11 46) SIGRTMIN + 12 47) SIGRTMIN + 13 48) SIGRTMIN + 14 49) SIGRTMIN + 15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX- 9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
Een signaal of virtuele interrupt is een bericht dat het systeem naar een proces stuurt, of het ene proces naar het andere stuurt. Wanneer het proces een signaal ontvangt, wordt de uitvoering van het procesprogramma onderbroken en wordt de besturing overgedragen aan de subroutine (functie) - de signaalbehandelaar. Na het uitvoeren van de signaalhandler, wordt de uitvoering van het onderbroken programma hervat vanaf het punt waarop het werd onderbroken.
Het besturingssysteem biedt: groot aantal soorten signalen, maar de meeste van deze typen zijn gereserveerd voor systeemdoeleinden - het zijn signalen die het besturingssysteem naar een proces stuurt. Er zijn echter ook signalen die processen met elkaar kunnen uitwisselen.
Standaard is de reactie op de meeste signalen om het proces dat het signaal heeft ontvangen te beëindigen, dat wil zeggen, als het proces een signaal ontvangt dat het niet voor verwerking levert, eindigt het proces dat het signaal ontvangt. Voor de meeste soorten signalen kan een proces echter een handler installeren dit signaal of ingesteld om dit signaal te negeren.
Als het proces zich in een "vrijwillig" onderbroken toestand bevindt (bijvoorbeeld veroorzaakt door de uitvoering van de slaapsysteemaanroep), ontvangt het slaapsysteem het signaal "ontwaakproces vanuit slaapstand", ongeacht wat het signaal is verwerkt, gesprek wordt direct beëindigd.
De signaalbehandelaar in het proces ziet eruit als een functie met een prototype:
Leegte functienaam(int tekentype);
De parameter van deze functie is het signaaltype (dezelfde handler kan worden geïnstalleerd om signalen van verschillende typen te verwerken).
De signaalsysteemoproep wordt gebruikt om uw signaalhandler in te stellen, te annuleren of in te stellen om het signaal te negeren.
Signaalafhandelingsfuncties zijn: normale functies C hebben ze toegang tot alle wereldwijd zichtbare variabelen en functies. Omdat we echter niet weten op welk punt in de uitvoering van het programma de handlerfunctie zal worden aangeroepen, moeten we extra voorzichtig zijn bij het benaderen van de globale datastructuren vanuit deze functie. Voor functies die threads verwerken, is er nog een: belangrijke eis:- herintreding. Aangezien een signaalbehandelaar op elk punt in de uitvoering van het programma kan worden aangeroepen (en onder bepaalde omstandigheden, tijdens de verwerking van het ene signaal, een andere signaalbehandelaar kan worden aangeroepen), moeten de behandelaars functies gebruiken die voldoen aan de eis van terugkeer, dat wil zeggen: ze kunnen op dat moment worden opgeroepen, terwijl ze al ergens anders in het programma worden opgeroepen. In feite komt de vereiste voor herintreding neer op het feit dat de functie geen wereldwijde bronnen gebruikt, zonder te zorgen voor synchronisatie van de toegang tot deze bronnen. Sommige I/O-functies, waaronder printf (), zijn niet reentrant. Dit betekent dat de uitvoer van de ene printf ()-functie kan worden verstoord door de uitvoer van een andere functie. Hieronder volgt een lijst met herintredende functies die veilig kunnen worden aangeroepen door signaalbehandelaars.
Lijst met herintredende functies
posix_trace_event () | |||
timer_getoverrun () | |||
Een proces kan een signaal sturen naar elk ander proces waarvan het de PID kent door de kill-systeemaanroep te gebruiken (ondanks de formidabele naam, doodt deze systeemaanroep niet noodzakelijk het proces waaraan het is geadresseerd). In sommige gevallen moet een proces een signaal naar zichzelf sturen, dit kan worden gedaan met behulp van de systeemaanroep verhogen.
Sommige soorten signalen
Signaaltypes worden geïdentificeerd door numerieke nummers, maar programmeren gebruikt vaak de symbolische signaalnamen die zijn gedefinieerd in system include-bestanden. Enkele van de meest gebruikte signaalnamen zijn:
Dit signaal beëindigt het proces dat het heeft ontvangen. Dit is het enige signaal dat niet kan worden genegeerd en waaraan geen eigen handler kan worden toegewezen. |
|
Dit signaal is een verzoek om het proces te beëindigen. Het afgeven van dit signaal omvat bijvoorbeeld het commando (geen systeemoproep!) Kill. Er wordt aangenomen dat het proces dat dit signaal ontvangt, moet stoppen, maar het proces kan ervoor kiezen om het signaal te negeren of zijn eigen handler toe te wijzen. |
|
Het systeem stuurt dit signaal naar het bovenliggende proces wanneer een van zijn onderliggende processen wordt beëindigd. De standaardreactie op dit signaal is negeren. Het bovenliggende proces kan dit signaal niet schelen, tenzij het het wil gebruiken om de uitvoering ervan te synchroniseren met het onderliggende proces. |
|
Dit signaal wordt gebruikt om tijdsintervallen te tellen. Het proces kan een bepaald tijdsinterval instellen met behulp van de alarm- of setitimer-systeemoproepen, en daarna: interval instellen het systeem stuurt er een SIGALRM-signaal naar toe. |
|
SIGUSR1 en SIGUSR2 |
|
Deze signalen zijn niet gereserveerd voor enige systeemtoewijzingen... Processen kunnen deze signalen naar elkaar sturen en naar eigen inzicht interpreteren. |
Voor meer details over signaaltypes, zie de functiebeschrijving