Ugrás a tartalomhoz

Szignál (informatika)

Ellenőrzött
A Wikipédiából, a szabad enciklopédiából

A jelfeldolgozás (signal processing) a számítástechnikában a folyamatközi kommunikáció(wd) 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(wd)) 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(wd) 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(wd) verziójában (1971) külön rendszerhívások(wd) 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(wd) (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(wd) 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(wd), a szegmentálási hiba(wd) (SIGSEGV) és a lebegőpontos kivétel (SIGFPE), memóriakiírást(wd) 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(wd) létrehozásakor.[7]

Bizonyos billentyűkombinációk begépelése egy futó folyamat vezérlőterminálján(wd) azt eredményezi, hogy a rendszer bizonyos jeleket küld neki:[8]

  • A Ctrl-C(wd)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(wd) 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-\(wd) billentyűkombináció egy QUIT jelet (SIGQUIT) küld; alapértelmezés szerint ez a folyamat leállítását és core dump(wd) kiíratást okoz.[6]
  • A Ctrl-T(wd) 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(wd) 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(wd) 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(wd)) 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(wd) 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(wd).[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(wd).[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(wd) 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(wd) kívül eső memóriacímet próbálna elérni, a kernel egy SIGSEGV (szegmentációs hiba(wd) 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(wd) 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(wd) é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 a wait() és waitpid() 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 a setitimer 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ó a sleep függvény implementációjával.
SIGBUS
A SIGBUS jel akkor kerül elküldésre egy folyamathoz, amikor buszhibát(wd) 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(wd) leáll(wd), 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(wd) rendszerhívás(wd) 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(wd).
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(wd)[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(wd) 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(wd)) megnyomásával lehet kezdeményezni, de egyes rendszereken a „delete(wd) vagy a „break(wd) 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(wd) 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(wd) 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(wd) 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(wd), 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(wd) (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(wd) 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(wd).
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(wd).[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(wd) 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(wd) 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(wd) 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(wd) megpróbál beolvasni vagy kiírni a tty-ből(wd). Ezeket a jeleket jellemzően csak a feladatvezérlés(wd) alatt álló folyamatok kapják meg; a démonoknak(wd)[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(wd) 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(wd) (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(wd)), 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és
  • SIGFPElebegőpontos kivétel (floating point exception)
  • SIGILL – "illegal", érvénytelen utasítás
  • SIGINT – "interrupt", interaktív figyelem-kérés küldve a programnak
  • SIGSEGV – "segmentation violation"(wd), érvénytelen memória-hozzáférés
  • SIGTERM – "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]
  1. Interprocess Communications. Microsoft
  2. A számítástechnikában az algoritmikus hatékonyság(wd) az algoritmusok azon tulajdonsága, amely az általuk felhasznált számítási erőforrások mennyiségéhez kapcsolódik.
  3. Sablon:Cite tech report
  4. C Programming in Plan 9 from Bell Labs. doc.cat-v.org . (Hozzáférés: 2022. január 22.)
  5. raise(3) — Linux manual page
  6. a b c d A számítástechnikában a core dump(wd), "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(wd) vagy más módon rendellenesen leállt.
  7. a b A Unix-szerű operációs rendszerekben a pipeline(wd) egy mechanizmus a folyamatok közötti kommunikációra(wd) üzenetküldés segítségével. A pipeline olyan Folyamat (számítástechnika)folyamatok halmaza, amelyeket szabványos adatfolyamaik(wd) láncolnak össze, így minden folyamat kimeneti szövege (stdout(wd)) közvetlenül bemenetként (stdin(wd)) 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.
  8. Termination Signals. The GNU C Library)
  9. Job Control Signals. The GNU C Library
  10. Miscellaneous Signals. The GNU C Library
  11. A Unix stty parancs egy Unix terminál beállításainak módosítására szolgál. (Version 2 AT&T UNIX )
  12. A számítástechnikában a sigaction(wd) 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.
  13. sigprocmask(2) — Linux manual page
  14. A PCLSRing (más néven Program Counter Lusering) az ITS operációs rendszerben(wd) használt kifejezés, amely a konzisztencia elvét jelöli, ahogyan az egyik folyamat egy másik folyamat állapotához(wd) fér hozzá.
  15. Alan Bawden: PCLSRing: Keeping Process State Modular
  16. A reentráns(wd) 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.
  17. signal(7) — Linux manual page
  18. 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.)
  19. signal(7) - Linux manual page. man7.org . (Hozzáférés: 2020. december 20.)
  20. signal-safety(7) — Linux manual page
  21. signal-safety(7) - Linux manual page. man7.org . (Hozzáférés: 2020. december 20.)
  22. 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.)
  23. A számítástechnikában az eseményciklus(wd) egy programozási konstrukció, vagy programtervezési minta, amely eseményekre vagy üzenetekre vár és azokat kiküldi egy programban.
  24. a b A számítástechnikában a laphiba(wd) 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(wd).
  25. A számítástechnikában a feladatkontextus (task context(wd)) a feladat(wd) (ami lehet egy folyamat, egy szál vagy egy rost(wd)) által használt minimális adathalmaz, amelyet menteni kell ahhoz, hogy a feladat megszakítható, majd később ugyanonnan folytatható legyen.
  26. What is an address space?. IBM . (Hozzáférés: 2024. május 5.)
  27. POSIX.1-2024
  28. 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.”
  29. 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(wd)) 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.
  30. 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.)
  31. 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.
  32. Egy leállított feladat folytatható háttérfeladatként a beépített bg paranccsal, vagy előtérfeladatként az fg 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.
  33. POSIX-kompatibilis platformokon a SIGHUP(wd) („signal hang up”) egy olyan jel, amelyet egy folyamatnak küldenek, amikor a vezérlő terminálja zárva van.
  34. 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.)
  35. a b A többfeladatos operációs rendszerekben a démon(wd) egy olyan számítógépes program, amely háttérfolyamatként(wd) fut, ahelyett, hogy egy interaktív felhasználó közvetlen irányítása alatt állna.
  36. Eric S. Raymond: daemon. The Jargon File. (Hozzáférés: 2008. október 22.)
  37. 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.)
  38. A nohup(wd) 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.
  39. Proper handling of SIGINT and SIGQUIT. (Hozzáférés: 2012. október 6.)
  40. Unix és Unix-szerű operációs rendszereken a zombifolyamat(wd) vagy megszűnt folyamat, amely befejezte a végrehajtást (az exit(wd) 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).
  41. 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.
  42. 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
  43. A ptrace(wd) 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.
  44. SIGKILL init process (PID 1). Stack Overflow
  45. Can root kill init process?. Unix & Linux Stack Exchange
  46. A megszakíthatatlan alvási állapot (uninterruptible sleep) olyan alvási állapot, amely nem képes azonnal jelet kezelni.
  47. 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.)
  48. ioctl - controls a STREAM device. POSIX system call specification. The Open Group. (Hozzáférés: 2015. június 19.)
  49. What is a "segmentation violation"?. support.microfocus.com . (Hozzáférés: 2018. november 22.)
  50. Syscall User Dispatch – The Linux Kernel documentation. kernel.org . (Hozzáférés: 2021. február 11.)
  51. getrlimit, setrlimit - control maximum resource consumption. POSIX system call specification. The Open Group. (Hozzáférés: 2009. szeptember 10.)
  52. 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”
  53. a b c signal(7) — Linux manual pages. manpages.courier-mta.org . (Hozzáférés: 2018. november 22.)
  54. Linux 3.0 x86_64: When is SIGSTKFLT raised?. Stack Overflow
  55. ISO/IEC 9899:1999 specification 
  56. The Open Group Base Specifications Issue 6 – signal.h – signals. (Hozzáférés: 2012. január 10.)
  57. 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.

További információk

[szerkesztés]