Szignál (informatika)
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).
Története
[szerkesztés]- 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]
Jelek küldése
[szerkesztés]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]
Jelek kezelése
[szerkesztés]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
[szerkesztés]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.
Kapcsolat hardveres kivételekkel
[szerkesztés]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.
POSIX jelek
[szerkesztés]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.
Signal | Portable number |
Default action | Description |
---|---|---|---|
SIGABRT | 6 | Terminate (core dump) | Folyamatmegszakítási jel (abort) |
SIGALRM | 14 | Terminate | Alarm clock |
SIGBUS | N/A | Terminate (core dump) | Hozzáférés egy memóriaobjektum meghatározatlan részéhez |
SIGCHLD | N/A | Ignore | Gyermekfolyamat leállt, megszakadt vagy folytatódott |
SIGCONT | N/A | Continue | Folytassa a végrehajtást, ha leállt |
SIGFPE | 8 | Terminate (core dump) | Hibás aritmetikai művelet |
SIGHUP | 1 | Terminate | Lefagyás (hangup) |
SIGILL | 4 | Terminate (core dump) | Érvénytelen utasítás |
SIGINT | 2 | Terminate | Terminál megszakításjel |
SIGKILL | 9 | Terminate | Kill (nem lehet elkapni vagy figyelmen kívül hagyni) |
SIGPIPE | 13 | Terminate | Írás csővezetékre, anélkül, hogy bárki elolvasná |
SIGQUIT | 3 | Terminate (core dump) | Terminál kilépési jel (quit) |
SIGSEGV | 11 | Terminate (core dump) | Érvénytelen memóriahivatkozás |
SIGSTOP | N/A | Stop | Végrehajtás leállítása (nem lehet elkapni vagy figyelmen kívül hagyni) |
SIGSYS | N/A | Terminate (core dump) | Hibás rendszerhívás |
SIGTERM | 15 | Terminate | Lezáró jel |
SIGTRAP | 5 | Terminate (core dump) | Nyomkövetési/töréspont-csapda |
SIGTSTP | N/A | Stop | Terminál leállító jelzés |
SIGTTIN | N/A | Stop | Háttérfolyamat próbálja meg olvasni |
SIGTTOU | N/A | Stop | Háttérfolyamat írási kísérlet |
SIGUSR1 | N/A | Terminate | Felhasználó által definiált jel 1 |
SIGUSR2 | N/A | Terminate | Felhasználó által definiált jel 2 |
SIGURG | N/A | Ignore | Sávon kívüli adatok érhetők el egy socketen keresztül |
SIGVTALRM | N/A | Terminate | Virtuális időzítő lejárt |
SIGXCPU | N/A | Terminate (core dump) | CPU időkorlát túllépve |
SIGXFSZ | N/A | Terminate (core dump) | Fájlméretkorlát túllépve |
SIGWINCH | N/A | Ignore | A terminálablak mérete megváltozott |
- 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]
Egyéb jelek
[szerkesztés]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]
C signal handling
[szerkesztés]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
[szerkesztés]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
[szerkesztés]- A
SIGTRAP
hibakeresési célokra szolgál. Platformfüggő, és Unix-szerű operációs rendszereken használható.
Kezelés
[szerkeszté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.
Függvények
[szerkesztés]Funkció | Leírása |
---|---|
raise
|
mesterségesen küld jelet a hívó folyamatnak |
kill
|
mesterségesen jelet küld egy megadott folyamatnak |
signal
|
beállítja a program által végrehajtott műveletet, amikor egy adott jelet kap |
Példa
[szerkesztés]#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
[szerkesztés]Jegyzetek
[szerkesztés]- ↑ Interprocess Communications. Microsoft
- ↑ A számítástechnikában az algoritmikus hatékonyság az algoritmusok azon tulajdonsága, amely az általuk felhasznált számítási erőforrások mennyiségéhez kapcsolódik.
- ↑ Sablon:Cite tech report
- ↑ C Programming in Plan 9 from Bell Labs. doc.cat-v.org . (Hozzáférés: 2022. január 22.)
- ↑ raise(3) — Linux manual page
- ↑ a b c d A számítástechnikában a core dump , "memóriakép" (memory dump, crash dump, storage dump, system dump, vagy ABEND dump) egy számítógépes program munkamemóriájának egy adott időpontban rögzített állapotát jelenti, általában akkor, amikor a program összeomlott vagy más módon rendellenesen leállt.
- ↑ a b A Unix-szerű operációs rendszerekben a pipeline egy mechanizmus a folyamatok közötti kommunikációra üzenetküldés segítségével. A pipeline olyan Folyamat (számítástechnika)folyamatok halmaza, amelyeket szabványos adatfolyamaik láncolnak össze, így minden folyamat kimeneti szövege (stdout ) közvetlenül bemenetként (stdin ) kerül a következő folyamatba. A második folyamat akkor indul el, amikor az első folyamat még fut, és a folyamatokat egyidejűleg hajtják végre.
- ↑ Termination Signals. The GNU C Library)
- ↑ Job Control Signals. The GNU C Library
- ↑ Miscellaneous Signals. The GNU C Library
- ↑ A Unix stty parancs egy Unix terminál beállításainak módosítására szolgál. (Version 2 AT&T UNIX )
- ↑ A számítástechnikában a sigaction egy POSIX által definiált függvény API, amely hozzáférést biztosít a programozónak ahhoz, hogy hogyan kell viselkednie egy programnak adott operációs rendszer-jelek fogadásakor.
- ↑ sigprocmask(2) — Linux manual page
- ↑ A PCLSRing (más néven Program Counter Lusering) az ITS operációs rendszerben használt kifejezés, amely a konzisztencia elvét jelöli, ahogyan az egyik folyamat egy másik folyamat állapotához fér hozzá.
- ↑ Alan Bawden: PCLSRing: Keeping Process State Modular
- ↑ A reentráns egy olyan programozási koncepció, ahol egy függvény vagy alprogram (eljárás) megszakítható, majd folytatható a végrehajtás befejezése előtt. Ez azt jelenti, hogy a függvény újra meghívható, mielőtt befejezné az előző végrehajtását. A reentráns kód rekurzívan hívható anélkül, hogy a változók kezelése hibát okozna. Ezért nem használhat statikus változókat megfelelő zárolás vagy egyéb adminisztráció nélkül.
- ↑ signal(7) — Linux manual page
- ↑ The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition: System Interfaces Chapter 2. pubs.opengroup.org . (Hozzáférés: 2020. december 20.)
- ↑ signal(7) - Linux manual page. man7.org . (Hozzáférés: 2020. december 20.)
- ↑ signal-safety(7) — Linux manual page
- ↑ signal-safety(7) - Linux manual page. man7.org . (Hozzáférés: 2020. december 20.)
- ↑ The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition: <signal.h>. pubs.opengroup.org . (Hozzáférés: 2020. december 20.)
- ↑ A számítástechnikában az eseményciklus egy programozási konstrukció, vagy programtervezési minta, amely eseményekre vagy üzenetekre vár és azokat kiküldi egy programban.
- ↑ a b A számítástechnikában a laphiba egy kivétel, amelyet a memóriakezelő egység (MMU) generál, amikor egy folyamat megfelelő előkészületek nélkül fér hozzá egy memórialaphoz .
- ↑ A számítástechnikában a feladatkontextus (task context ) a feladat (ami lehet egy folyamat, egy szál vagy egy rost ) által használt minimális adathalmaz, amelyet menteni kell ahhoz, hogy a feladat megszakítható, majd később ugyanonnan folytatható legyen.
- ↑ What is an address space?. IBM . (Hozzáférés: 2024. május 5.)
- ↑ POSIX.1-2024
- ↑ IEEE Std 1003.1-2017 - kill. IEEE, Open Group. „The correspondence between integer values and the sig value used is shown in the following list. The effects of specifying any signal_number other than those listed below are undefined.”
- ↑ Egy számítógépes vagy adatátviteli rendszerben a megszakítás egy feldolgozási tevékenység – általában ellenőrzött módon történő – leállítását (abort ) jelenti, mivel a tevékenység folytatása lehetetlen vagy nem kívánatos, illetve ha hiba történik. Az ilyen műveletet a megszakított folyamatra vonatkozó diagnosztikai információk kísérhetik.
- ↑ What is Abort? (angol nyelven). www.computerhope.com . [2019. április 22-i dátummal az eredetiből archiválva]. (Hozzáférés: 2019. április 22.)
- ↑ A számítástechnikában a buszhiba (bus error) egy hardver által okozott hiba, amely értesíti az operációs rendszert, hogy egy folyamat olyan memóriához próbál hozzáférni, amelyet a CPU fizikailag nem tud megcímezni: érvénytelen cím a címbuszhoz, innen ered a név is.
- ↑ Egy leállított feladat folytatható háttérfeladatként a beépített
bg
paranccsal, vagy előtérfeladatként azfg
paranccsal. Mindkét esetben a shell megfelelően átirányítja az I/O-t, és elküldi a SIGCONT jelet a folyamatnak, aminek hatására az operációs rendszer folytatja a végrehajtást. A Bash-ben egy program háttérfeladatként indítható egy és jel (&
) hozzáfűzésével a parancssorhoz; a kimenete a terminálra kerül (potenciálisan összefonódva más programok kimenetével), de a terminál bemenetéről nem tud olvasni. - ↑ POSIX-kompatibilis platformokon a SIGHUP („signal hang up”) egy olyan jel, amelyet egy folyamatnak küldenek, amikor a vezérlő terminálja zárva van.
- ↑ Michael Kerrisk: signal(7). Linux Programmer's Manual (version 3.22). The Linux Kernel Archives, 2009. július 25. (Hozzáférés: 2009. szeptember 23.)
- ↑ a b A többfeladatos operációs rendszerekben a démon egy olyan számítógépes program, amely háttérfolyamatként fut, ahelyett, hogy egy interaktív felhasználó közvetlen irányítása alatt állna.
- ↑ Eric S. Raymond: daemon. The Jargon File. (Hozzáférés: 2008. október 22.)
- ↑ perlipc(1). Perl Programmers Reference Guide, version 5.18. perldoc.perl.org - Official documentation for the Perl programming language. (Hozzáférés: 2013. szeptember 21.)
- ↑ A nohup egy POSIX parancs, ami azt jelenti, hogy „nincs lefagyás” (no hang up). Célja, hogy egy parancsot úgy hajtson végre, hogy figyelmen kívül hagyja a HUP (hangup – lefagyás) jelet, és így ne álljon le, amikor a felhasználó kijelentkezik.
- ↑ Proper handling of SIGINT and SIGQUIT. (Hozzáférés: 2012. október 6.)
- ↑ Unix és Unix-szerű operációs rendszereken a zombifolyamat vagy megszűnt folyamat, amely befejezte a végrehajtást (az
exit
rendszerhíváson keresztül), de még mindig van bejegyzés a folyamattáblában: ez egy "megszakított állapotban lévő folyamat" (terminated state). - ↑ Unix alapú operációs rendszerekben az init (az inicializálás rövidítése) az első folyamat, amely az operációs rendszer indításakor elindul.
- ↑ https://manpages.ubuntu.com/manpages/zesty/man2/kill.2.html Archiválva 2018. január 28-i dátummal a Wayback Machine-ben. section NOTES
- ↑ A ptrace egy rendszerhívás (a „process trace” rövidítése), amely használatával egy folyamat vezérelhet egy másikat, lehetővé téve a vezérlő számára, hogy megvizsgálja és manipulálja a célpont belső állapotát.
- ↑ SIGKILL init process (PID 1). Stack Overflow
- ↑ Can root kill init process?. Unix & Linux Stack Exchange
- ↑ A megszakíthatatlan alvási állapot (uninterruptible sleep) olyan alvási állapot, amely nem képes azonnal jelet kezelni.
- ↑ Mac Dev Center: What's New in Mac OS X: Mac OS X v10.6, 2009. augusztus 28. (Hozzáférés: 2017. november 18.)
- ↑ ioctl - controls a STREAM device. POSIX system call specification. The Open Group. (Hozzáférés: 2015. június 19.)
- ↑ What is a "segmentation violation"?. support.microfocus.com . (Hozzáférés: 2018. november 22.)
- ↑ Syscall User Dispatch – The Linux Kernel documentation. kernel.org . (Hozzáférés: 2021. február 11.)
- ↑ getrlimit, setrlimit - control maximum resource consumption. POSIX system call specification. The Open Group. (Hozzáférés: 2009. szeptember 10.)
- ↑ Clausecker, Robert: 0001151: Introduce new signal SIGWINCH and functions tcsetsize(), tcgetsize() to get/set terminal window size. Austin Group Defect Tracker . Austin Group, 2017. június 19. (Hozzáférés: 2017. október 12.) „Accepted As Marked”
- ↑ a b c signal(7) — Linux manual pages. manpages.courier-mta.org . (Hozzáférés: 2018. november 22.)
- ↑ Linux 3.0 x86_64: When is SIGSTKFLT raised?. Stack Overflow
- ↑ ISO/IEC 9899:1999 specification
- ↑ The Open Group Base Specifications Issue 6 – signal.h – signals. (Hozzáférés: 2012. január 10.)
- ↑ https://man7.org/linux/man-pages/man2/signal.2.html Signal(2) manpage
Fordítás
[szerkesztés]Ez a szócikk részben vagy egészben a Signal (IPC) című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.