Szignál (informatika)
jelfeldolgozás From Wikipedia, the free encyclopedia
Remove ads
A jelfeldolgozás (signal processing) a számítástechnikában a folyamatközi kommunikáció egyik formája,[1] amit a POSIX-szabványú operációs rendszerek alkalmaznak.
A jelek (signal) szabványosított üzenetek, amelyeket egy futó programnak küldenek, hogy adott viselkedést, például kilépést vagy hibakezelést indítsanak el. Ezek a folyamatok közötti kommunikáció (IPC ) korlátozott formáját jelentik, amelyeket jellemzően Unix, Unix-szerű és más POSIX-kompatibilis operációs rendszerekben használnak.
A jel (szignál) egy aszinkron értesítés, amelyet egy folyamatnak vagy ugyanazon a folyamaton belüli adott szálnak (thread) küldenek, hogy értesítsék egy eseményről. A jelek gyakori felhasználási módjai egy folyamat megszakítása, felfüggesztése, leállítása vagy „megölése”. A jelek az 1970-es évekbeli Bell Labs Unixból származnak, majd később a POSIX szabványban is specifikálták őket.
Amikor egy jel elküldésre kerül, az operációs rendszer megszakítja a célfolyamat normál végrehajtási folyamatát a jel kézbesítése érdekében. A végrehajtás bármely nem atomi utasítás során megszakítható. Ha a folyamat korábban regisztrált egy jelkezelőt (signal handler), akkor az a rutin végrehajtódik. Ellenkező esetben az alapértelmezett jelkezelő kerül végrehajtásra.
A beágyazott programok hasznosnak találhatják a jeleket a folyamatok közötti kommunikációhoz, mivel a jelek algoritmikus hatékonyságukról ismertek.[2]
A jelek hasonlóak a megszakításokhoz, a különbség az, hogy a megszakításokat a CPU közvetíti és a kernel kezeli, míg a jeleket a kernel közvetíti (esetleg rendszerhívásokon keresztül) és az egyes folyamatok kezelik. A kernel átadhat egy megszakítást jelként annak a folyamatnak, amely azt okozta (tipikus példák a SIGSEGV, SIGBUS, SIGILL és SIGFPE).
Remove ads
Története
- Az Unix 1-es verziójában (1971) külön rendszerhívások voltak a megszakítások, kilépések és gépi csapdák elkapására.
- A kill a 2. verzióban (1972) jelent meg.
- A 4. verzió (1973) az összes csapdát egyetlen hívássá, jelzéssé egyesítette.
- Az 5-ös verzió (1974) tetszőleges jeleket küldhetett.[3]
- A 7. verzióban (1979) minden számozott csapda szimbolikus nevet kapott.
- A Plan 9 a Bell Labs-tól (80-as évek vége) a jeleket jegyzetekkel helyettesítette, amelyek lehetővé tették rövid, tetszőleges karakterláncok küldését.[4]
Remove ads
Jelek küldése
A kill(2) rendszerhívás egy megadott jelet küld egy megadott folyamatnak, ha a jogosultságok megengedik. Hasonlóképpen, a kill(1) parancs lehetővé teszi a felhasználó számára, hogy jeleket küldjön a folyamatoknak. A raise(3)[5] könyvtárfüggvény elküldi a megadott jelet az aktuális folyamatnak.
Az olyan kivételek, mint a nullával való osztás , a szegmentálási hiba (SIGSEGV) és a lebegőpontos kivétel (SIGFPE), memóriakiírást okoznak[6] és leállítják a programot.
A kernel jeleket generálhat a folyamatok eseményekről való értesítésére. Például a SIGPIPE akkor generálódik, amikor egy folyamat egy olyan pipe-ra[7] ír, amelyet az olvasó lezárt; alapértelmezés szerint ez a folyamat leállítását okozza, ami kényelmes a shell pipeline-ok létrehozásakor.[7]
Bizonyos billentyűkombinációk begépelése egy futó folyamat vezérlőterminálján azt eredményezi, hogy a rendszer bizonyos jeleket küld neki:[8]
- A Ctrl-C Ctrl-C (régebbi Unixokban DEL) egy INT jelet küld ("interrupt", SIGINT); alapértelmezés szerint ez a folyamat leállítását okozza.
- A Ctrl+Z billentyűkombináció egy TSTP jelet küld ("terminal stop", SIGTSTP); alapértelmezés szerint ez a folyamat végrehajtásának felfüggesztését okozza.[9]
- A Ctrl-\ billentyűkombináció egy QUIT jelet (SIGQUIT) küld; alapértelmezés szerint ez a folyamat leállítását és core dump kiíratást okoz.[6]
- A Ctrl-T billentyűkombináció (nem minden UNIX rendszeren támogatott) egy INFO jelet (SIGINFO) küld; alapértelmezés szerint, és ha a parancs támogatja, ez azt eredményezi, hogy az operációs rendszer információkat jelenít meg a futó parancsról.[10]
Ezek az alapértelmezett billentyűkombinációk a modern operációs rendszerekkel az stty paranccsal módosíthatók.[11]
Remove ads
Jelek kezelése
A jelkezelők a signal(2) vagy a sigaction(2) rendszerhívással telepíthetők.[12] Ha egy adott jelhez nincs telepítve jelkezelő, akkor az alapértelmezett kezelőt használja a rendszer. Ellenkező esetben a jel elfogásra kerül, és a jelkezelő meghívódik. A folyamat két alapértelmezett viselkedést is megadhat kezelő létrehozása nélkül: a jel figyelmen kívül hagyása (SIG_IGN) és az alapértelmezett jelkezelő (SIG_DFL) használata. Két jel van, amelyet nem lehet elfogni és kezelni: a SIGKILL és a SIGSTOP.
Kockázatok
A jelkezelés érzékeny a versenyhelyzetekre. Mivel a jelek aszinkronok, egy másik jel (akár azonos típusú is) a jelkezelő rutin végrehajtása során is eljuthat a folyamathoz.
A sigprocmask(2) hívás használható a jelek kézbesítésének blokkolására és feloldására.[13] A blokkolt jelek nem kerülnek kézbesítésre a folyamathoz, amíg a blokkolást fel nem oldják. A nem figyelmen kívül hagyható jeleket (SIGKILL és SIGSTOP) nem lehet blokkolni.
A jelek megszakíthatják a folyamatban lévő rendszerhívást, így az alkalmazásra marad a nem transzparens újraindítás kezelése.[14][15]
A jelkezelőket úgy kell megírni, hogy ne okozzanak semmilyen nem kívánt mellékhatást, pl. hibakód (errno ) megváltozását, jelmaszk megváltozását, jelelrendezés megváltozását és egyéb globális folyamatattribútum-változásokat. A nem-reentráns függvények,[16] például a malloc vagy a printf használata a jelkezelő rutinokon belül szintén nem biztonságos. A POSIX specifikáció és a Linux man page signal(7) előírja,[17] hogy a jelfüggvényből közvetlenül vagy közvetve meghívott összes rendszerfüggvény aszinkronjel-biztos legyen.[18][19] A signal-safety(7) man oldal[20] felsorolja az ilyen aszinkronjel-biztos rendszerfüggvényeket (gyakorlatilag a rendszerhívásokat), egyébként ez egy nem definiált viselkedés .[21] Javasolt egyszerűen beállítani valamilyen volatile sig_atomic_t
változót egy jelkezelőben, és máshol tesztelni.[22]
A jelkezelők ehelyett elhelyezhetik a jelet egy várakozási sorba, és azonnal visszatérhetnek. A fő szál ezután „megszakítás nélkül” folytatódik, amíg a jeleket el nem veszik a várakozási sorból, például egy eseményhurokban .[23] A „megszakítás nélküli” itt azt jelenti, hogy a blokkoló műveletek idő előtt visszatérhetnek, és a fent említett módon folytatni kell őket. A jeleket a fő szálon lévő várakozási sorból kell feldolgozni, nem pedig a munkavégző készletekből, mivel ez újra bevezeti az aszinkronitás problémáját. Egy várakozási sor kezelése azonban nem lehetséges aszinkronjel-biztonságos módon, kizárólag a sig_atomic_t
változóval, mivel az ilyen változókba történő írások és olvasások garantáltan atomiak, nem pedig növelések vagy (lehívások és) csökkentések, ahogyan az egy várakozási sor esetében megkövetelhető lenne. Így gyakorlatilag kezelőnként csak egy jel kerülhet biztonságosan sorba a sig_atomic_t
segítségével, amíg azt fel nem dolgozza.
Remove ads
Kapcsolat hardveres kivételekkel
Egy folyamat végrehajtása hardveres kivétel generálódását eredményezheti, például, ha a folyamat nullával próbál osztani, vagy laphiba keletkezik.[24]
Unix-szerű operációs rendszerekben ez az esemény automatikusan megváltoztatja a processzor kontextusát,[25] hogy elindítsa a kernel kivételkezelőjének végrehajtását. Bizonyos kivételek, például egy laphiba[24] esetén a kernel elegendő információval rendelkezik ahhoz, hogy teljes mértékben kezelje az eseményt, és folytassa a folyamat végrehajtását.
Más kivételek esetén azonban a kernel nem képes intelligensen feldolgozni a hibákat, és ehelyett a kivételkezelési műveletet a hibás folyamatra kell halasztania. Ez a halasztás a jelzés mechanizmusán keresztül valósul meg, ahol a kernel az aktuális kivételnek megfelelő jelet küld a folyamatnak. Például, ha egy folyamat egész számot próbál nullával osztani egy x86 CPU-n, akkor egy osztási hiba (divide error) kivétel keletkezik, és a kernel elküldi az SIGFPE jelet a folyamatnak.
Hasonlóképpen, ha a folyamat a virtuális címtartományán kívül eső memóriacímet próbálna elérni, a kernel egy SIGSEGV (szegmentációs hiba jel) segítségével értesítené a folyamatot erről a megsértésről.[26] A jelnevek és a kivételek közötti pontos megfeleltetés nyilvánvalóan a CPU-tól függ, mivel a kivételtípusok architektúránként eltérőek.
Remove ads
POSIX jelek
Az alábbi lista a Single Unix Specification 5. verziójában meghatározott jeleket (signal) dokumentálja.[27] Minden jel makró konstansként van definiálva a <signal.h>
fejlécfájlban. A makró konstans neve egy "SIG" előtagból áll, amelyet a jel mnemonikus neve követ.
Egy folyamat meghatározhatja, hogyan kezelje a bejövő POSIX jeleket. Ha egy folyamat nem definiál viselkedést egy jelhez, akkor az adott jel alapértelmezett kezelőjét (default handler) használja. Az alábbi táblázat néhány alapértelmezett műveletet sorol fel POSIX-kompatibilis UNIX rendszereken, például a FreeBSD-n, az OpenBSD-n és a Linuxon.
- Portable number:
A legtöbb jel esetében a megfelelő jelszám implementáció által definiált. Ez az oszlop a POSIX szabványban meghatározott számokat sorolja fel.[28]
- Actions explained:
- Terminate – A folyamat rendellenes leállítása. A folyamat az
_exit()
összes következményével leáll, azzal a kivétellel, hogy await()
éswaitpid()
számára elérhetővé tett állapot a megadott jel általi rendellenes leállítást jelzi. - Terminate (core dump) – A folyamat rendellenes leállítása. Ezenkívül előfordulhatnak implementáció által meghatározott rendellenes leállítási műveletek, például egy core-fájl létrehozása.[6]
- Ignore – Ne törődj a jelzéssel.
- Stop – Állítsa le (vagy függessze fel) a folyamatot.
- Continue – Folytassa a folyamatot, ha leállt; ellenkező esetben hagyja figyelmen kívül a jelzést.
- SIGABRT és SIGIOT
- A SIGABRT jelet egy folyamatnak küldik, hogy utasítsák a futás megszakítására, azaz a leállítására.[29] A jelet általában maga a folyamat kezdeményezi, amikor meghívja a C Standard Library
abort()
függvényét, de kívülről is küldhető a folyamatnak, mint bármely más jel.[30] - A SIGIOT azt jelzi, hogy a CPU egy explicit "trap" utasítást hajtott végre (definiált függvény nélkül), vagy egy nem implementált utasítást (amikor az emuláció nem érhető el).
- Megjegyzés: az „input/output trap” (bemeneti/kimeneti csapda) félrevezető elnevezés a CPU "trap" utasításaira. A kifejezés az ilyen utasítások korai használatára utal, főként I/O funkciók megvalósítására, de ezek nem feltétlenül kötődnek az eszköz I/O-jához, és más célokra is használhatók, például virtuális és valós hosztok közötti kommunikációra.
- A SIGIOT és a SIGABRT jellemzően ugyanaz a jel, és a jel vétele a fenti feltételek bármelyikét jelezheti.
- SIGALRM, SIGVTALRM és SIGPROF
- A SIGALRM, SIGVTALRM és SIGPROF jeleket a rendszer elküldi a folyamatnak, amikor a megfelelő időkorlátot eléri. A folyamat az
alarm
vagy asetitimer
meghívásával állítja be ezeket az időkorlátokat. A SIGALRM időkorlátja a valós vagy az óraidőn alapul; a SIGVTALRM a folyamat által felhasznált CPU-időn alapul; a SIGPROF pedig a folyamat és a nevében a rendszer által felhasznált CPU-időn (profiling timer-ként ismert). Egyes rendszereken a SIGALRM belsőleg használható asleep
függvény implementációjával. - SIGBUS
- A SIGBUS jel akkor kerül elküldésre egy folyamathoz, amikor buszhibát okoz.[31] A jel küldéséhez vezető feltételek lehetnek például a memória-hozzáférés helytelen illesztése vagy a nem létező fizikai cím.
- SIGCHLD
- A SIGCHLD jelet egy folyamat kapja meg, amikor egy gyermekfolyamat leáll , vagy leállítás után újraindul. A jel egyik gyakori felhasználási módja az operációs rendszer utasítása a gyermekfolyamat által a leállítás után felhasznált erőforrások megtisztítására a
wait
rendszerhívás explicit meghívása nélkül. - SIGCONT
- A SIGCONT jel arra utasítja az operációs rendszert, hogy folytassa (újraindítsa) a SIGSTOP vagy SIGTSTP jel által korábban szüneteltetett folyamatot.[32] Ennek a jelnek az egyik fontos felhasználási módja a Unix shell feladatvezérlése .
- SIGFPE
- A SIGFPE jelet egy folyamat kapja meg, amikor kivételes (de nem feltétlenül hibás) feltételt észlel a lebegőpontos vagy egész számot kezelő hardverben. Ez lehet nullával osztás, lebegőpontos alul- vagy túlcsordulás, egész szám túlcsordulás, érvénytelen művelet vagy pontatlan számítás. A viselkedés a hardvertől függően eltérő lehet.
- SIGHUP
- A SIGHUP jelet akkor küldik a folyamatnak, amikor a vezérlő terminálja zárva van.[33] Eredetileg arra tervezték, hogy értesítse a folyamatot a soros vonal megszakadásáról (egy lefagyásról). A modern rendszerekben ez a jel általában azt jelenti, hogy a vezérlő pszeudo- vagy virtuális terminál zárva van.[34] Sok démon[35][36] (amelyeknek nincs vezérlő terminálja) a jel vételét a konfigurációs fájljaik újratöltésére és a naplófájlok kiürítésére/újranyitására vonatkozó kérésként értelmezi kilépés helyett.[37] A nohup egy parancs, amivel egy parancs figyelmen kívül hagyhatja a jelet.[38]
- SIGILL
- A SIGILL jelet akkor küldik egy folyamatnak, amikor az illegális, hibásan formázott, ismeretlen vagy privilegizált utasítást kísérel meg végrehajtani.
- SIGINT
- A SIGINT jelet a vezérlő terminál küldi a folyamatnak, amikor a felhasználó meg akarja szakítani (interrupt) a folyamatot. Ezt jellemzően a Ctrl+C billentyűkombináció (Control-C ) megnyomásával lehet kezdeményezni, de egyes rendszereken a „delete” vagy a „break” billentyű is használható.[39]
- SIGKILL
- A SIGKILL jelet egy folyamatnak küldik, hogy azonnal leállítsa azt (kill). A SIGTERM és SIGINT jellel ellentétben ezt a jelet nem lehet elkapni vagy figyelmen kívül hagyni, és a fogadó folyamat nem tud semmilyen tisztítást végrehajtani a jel vétele után. A következő kivételek érvényesek:
- A zombi folyamatok nem ölhetők le, mivel már halottak és arra várnak, hogy a szülő folyamataik learassák őket.[40]
- A blokkolt állapotban lévő folyamatok nem halnak meg, amíg újra nem ébrednek.
- Az init folyamat[41] speciális: nem kap olyan jeleket, amelyeket nem akar kezelni, így figyelmen kívül hagyhatja a SIGKILL-t.[42] Kivételt képez ez alól a szabály alól a Linuxon futó init[43] függvény.[44][45]
- Egy megszakítás nélkül alvó folyamat[46] SIGKILL utasítás küldése után sem feltétlenül fejeződik be (és nem szabadítja fel az erőforrásait). Ez egyike azon kevés eseteknek, amikor egy UNIX rendszert újra kell indítani egy ideiglenes szoftverprobléma megoldásához.
- A SIGKILL-t a legtöbb rendszerleállítási eljárásban a folyamatok leállításakor végső megoldásként használják, ha a SIGTERM parancsra válaszul nem lép ki önként. A számítógép leállítási folyamatának felgyorsítása érdekében a Mac OS X 10.6, más néven Snow Leopard , SIGKILL kódot küld azoknak az alkalmazásoknak, amelyek „tisztának” jelölték meg magukat, ami gyorsabb leállítási időt eredményez, feltehetően káros hatások nélkül.[47] A
killall -9
parancs hasonló, bár veszélyes hatással bír, például Linux alatt végrehajtva; nem engedi, hogy a programok mentsék a nem mentett adatokat. Vannak más beállításai is, és ha nincsenek, akkor a biztonságosabb SIGTERM jelet használja. - SIGPIPE
- A SIGPIPE jelet egy folyamat kapja meg, amikor az egy olyan pipe-ra (csővezeték) próbál írni, amelyhez nincs csatlakoztatva folyamat.
- SIGPOLL
- A SIGPOLL jel akkor kerül elküldésre, amikor egy esemény történik egy explicit módon figyelt fájlleírón.[48] Használata gyakorlatilag aszinkron I/O kérések küldéséhez vezet, mivel a kernel a leírót kérdezi le a hívó helyett. Alternatívát kínál az aktív lekérdezésre .
- SIGRTMIN – SIGRTMAX
- A SIGRTMIN-től SIGRTMAX-ig terjedő jelek felhasználó által meghatározott célokra szolgálnak. Ezek valós idejű jelek.
- SIGQUIT
- A SIGQUIT jelet a vezérlő terminál küldi a folyamatnak, amikor a felhasználó kéri, hogy a folyamat kilépjen és végrehajtson egy memóriakiíratást .[6]
- SIGSEGV
- A SIGSEGV jelet akkor küldik egy folyamatnak, amikor érvénytelen virtuális memória referenciát, vagy szegmentálási hibát okoz, azaz amikor szegmentációs szabálysértést (segmentation violation) hajt végre.[49]
- SIGSTOP
- A SIGSTOP jel arra utasítja az operációs rendszert, hogy állítsa le a folyamatot a későbbi folytatás érdekében.
- SIGSYS
- A SIGSYS jelet egy folyamat kapja meg, amikor rossz argumentumot ad át egy rendszerhívásnak. A gyakorlatban ez a fajta jel ritkán fordul elő, mivel az alkalmazások könyvtárakra (pl. libc) támaszkodnak a hívásukhoz. A SIGSYS jelet olyan alkalmazások kaphatják, amelyek megsértik a korlátozásukra konfigurált Linux Seccomp biztonsági szabályokat. A SIGSYS idegen rendszerhívások emulálására is használható, pl. Windows rendszerhívások emulálására Linuxon.[50]
- SIGTERM
- A SIGTERM jellel a folyamat lezárását kéri. A SIGKILL jellel ellentétben a folyamat elkaphatja és értelmezheti, vagy figyelmen kívül hagyhatja. Ez lehetővé teszi a folyamat számára, hogy igény szerint leállítsa a folyamatot, erőforrásokat szabadítson fel és szükség esetén mentse az állapotot. A SIGINT szinte azonos a SIGTERM jellel.
- SIGTSTP
- A SIGTSTP jelet a vezérlő terminál küldi a folyamatnak, hogy kérje annak leállítását (terminál leállítás). A jelet általában a felhasználó kezdeményezi, aki megnyomja a Ctrl+Z billentyűkombinációt. A SIGSTOP-pal ellentétben a folyamat regisztrálhat egy jelkezelőt a jelhez, vagy figyelmen kívül hagyhatja a jelet.
- SIGTTIN és SIGTTOU
- A SIGTTIN és SIGTTOU jeleket egy folyamat kapja meg, amikor a háttérben megpróbál beolvasni vagy kiírni a tty-ből . Ezeket a jeleket jellemzően csak a feladatvezérlés alatt álló folyamatok kapják meg; a démonoknak[35] nincsenek vezérlő termináljaik, ezért soha nem szabadna megkapniuk ezeket a jeleket.
- SIGTRAP
- A SIGTRAP jelet egy folyamat akkor kapja meg, amikor kivétel (vagy trap) történik: egy olyan feltétel, amelyről a hibakereső információt kért – például amikor egy adott függvény végrehajtódik, vagy amikor egy adott változó értéke megváltozik.
- SIGURG
- A SIGURG jel akkor kerül elküldésre egy folyamatnak, amikor egy socket sürgős vagy sávon kívüli adatokkal rendelkezik olvasásra.
- SIGUSR1 és SIGUSR2
- A SIGUSR1 és SIGUSR2 jeleket egy folyamatnak küldik, hogy jelezzék a felhasználó által definiált feltételeket.
- SIGXCPU
- A SIGXCPU jelet akkor küldi el egy folyamat, ha az a CPU-t egy előre meghatározott, felhasználó által beállítható értéket meghaladó ideig használta.[51] Egy SIGXCPU jel megérkezése lehetőséget ad a fogadó folyamatnak a köztes eredmények gyors mentésére és a szabályos kilépésre, mielőtt az operációs rendszer a SIGKILL jellel leállítaná.
- SIGXFSZ
- A SIGXFSZ jelet egy folyamat kapja meg, amikor egy fájl mérete meghaladja a maximálisan megengedett méretet.
- SIGWINCH
- A SIGWINCH jelet egy folyamat kapja meg, amikor a vezérlő terminálja megváltoztatja a méretét (window change).[52]
Remove ads
Egyéb jelek
A következő jelek nincsenek meghatározva a POSIX specifikációban. Azonban néha különböző rendszereken használják őket.
- SIGEMT
- A SIGEMT jelet egy folyamathoz küldik, amikor emulátorcsapda (emulator trap) történik. Míg az emulátor általában olyan szoftvert jelent, amely más programokat hajt végre, ebben az esetben azt jelenti, hogy egy program végrehajtott egy felügyelői hívási utasítást (az EMT utasítás volt erre a célra a DEC PDP–11 sorozatú számítógépeken).
- SIGINFO
- A SIGINFO jel akkor kerül elküldésre a folyamatnak, amikor egy állapot (info) kérés érkezik a vezérlő termináltól.
- SIGPWR
- A SIGPWR jelet egy folyamat kapja meg, amikor a rendszer áramkimaradást (power failure) tapasztal.
- SIGLOST
- A SIGLOST jel akkor kerül elküldésre egy folyamatnak, amikor egy fájlzárolás elvész (lost).
- SIGSTKFLT
- A SIGSTKFLT jelet akkor küldi el egy folyamatnak, amikor a koprocesszor veremhibát (stack fault) tapasztal (azaz kiugrik, amikor a verem üres, vagy push-olja, amikor megtelt).[53] Linuxon definiálják, de nem használják, ahol egy x87 társprocesszoros veremhiba SIGFPE-t generál.[54]
- SIGUNUSED
- A SIGUNUSED jel akkor kerül elküldésre egy folyamatnak, amikor egy nem használt (unused) rendszerhívási számmal rendelkező rendszerhívás történik. A legtöbb architektúrán ez a SIGSYS szinonimája.[53]
- SIGCLD
- Az SIGCLD jel a SIGCHLD jel szinonimája.[53]
Remove ads
C signal handling
A szabványos C-könyvtárban a jelfeldolgozás (signal processing) határozza meg, hogy egy program hogyan kezeli a különböző jeleket végrehajtás közben. Egy jel (signal) jelenthet valamilyen kivételes viselkedést a programon belül (például nullával való osztást ), vagy egy jel jelenthet valamilyen aszinkron eseményt a programon kívül (például, hogy valaki lenyom egy interaktív figyelem billentyűt a billentyűzeten).
Standard jelek
A C szabvány csak 6 jelet definiál. Mindegyik a signal.h
fejlécben van definiálva (C++-ban a csignal
fejléc):[55]
SIGABRT
– "abort", rendellenes befejezésSIGFPE
– lebegőpontos kivétel (floating point exception)SIGILL
– "illegal", érvénytelen utasításSIGINT
– "interrupt", interaktív figyelem-kérés küldve a programnakSIGSEGV
– "segmentation violation" , érvénytelen memória-hozzáférésSIGTERM
– "terminate", leállítási kérés elküldve a programnak
A megvalósítás további jeleket is megadhat a signal.h
fejlécben. Például a Unix és az Unix-szerű operációs rendszerek (mint például a Linux) több mint 15 további jelet definiálnak.[56]
Hibakeresés
- A
SIGTRAP
hibakeresési célokra szolgál. Platformfüggő, és Unix-szerű operációs rendszereken használható.
Kezelés
Jel generálható a signal()
vagy sigaction()
rendszerhívások meghívásával. A raise()
jelet küld az aktuális folyamatnak, a kill()
pedig egy adott folyamatnak.
A jelkezelő egy olyan függvény, amelyet a célkörnyezet hív meg, amikor a megfelelő jel megjelenik. A célkörnyezet felfüggeszti a program végrehajtását, amíg a jelkezelő vissza nem tér vagy meg nem hívja a longjmp()
függvényt.
A jelkezelők a signal()
vagy a sigaction()
függvénnyel állíthatók be. A signal()
viselkedése a történelem során többször is megváltozott, és használatát nem javasoljuk.[57] Csak akkor hordozható, ha egy jel diszpozícióját SIG_DFL-re vagy SIG_IGN-re állítjuk be vele. Jelkezelők két jel kivételével minden jelhez megadhatók (a SIGKILL és a SIGSTOP nem fogható el, nem blokkolható és nem is hagyható figyelmen kívül.).
Ha a jel hibát jelez a programon belül (és a jel nem aszinkron), a jelkezelő az abort()
, exit()
vagy longjmp()
meghívásával leállíthatja a futást.
Remove ads
Függvények
Példa
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
volatile sig_atomic_t status = 0;
static void catch_function(int signo) {
status = signo;
}
int main(void) {
// Állítsa be a fenti függvényt a SIGINT jel kezelőjeként:
if (signal(SIGINT, catch_function) == SIG_ERR) {
fputs("An error occurred while setting a signal handler.\n", stderr);
return EXIT_FAILURE;
}
puts("Raising the interactive attention signal.");
if (raise(SIGINT)) {
fputs("Error raising the signal.\n", stderr);
return EXIT_FAILURE;
}
if (status == SIGINT) puts("Interactive attention signal caught.");
puts("Exiting.");
return EXIT_SUCCESS;
// exiting after raising signal
}
Kapcsolódó szócikkek
Jegyzetek
Fordítás
További információk
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads