Signál (IPC) - Signal (IPC)

Signály jsou standardizované zprávy odesílané do spuštěného programu, aby spustily specifické chování, například ukončení nebo zpracování chyb. Jedná se o omezenou formu meziprocesové komunikace (IPC), která se obvykle používá v operačních systémech Unix , Unix a dalších kompatibilních s POSIX .

Signál je asynchronní oznámení odeslané do procesu nebo do určitého vlákna v rámci stejného procesu, které ho upozorní na událost. Běžné použití signálů jsou přerušit, pozastavit, ukončit nebo zabít proces. Signály vznikly v Unixu společnosti Bell Labs v sedmdesátých letech a později byly specifikovány ve standardu POSIX .

Když je odeslán signál, operační systém přeruší normální tok provedení cílového procesu, aby signál doručil. Provádění může být přerušeno během jakékoli neatomové instrukce . Pokud proces dříve zaregistroval obslužný program signálu , provede se tato rutina. V opačném případě se provede výchozí obsluha signálu.

Vestavěné programy mohou najít signály užitečné pro meziprocesovou komunikaci, protože signály jsou pozoruhodné svou algoritmickou účinností .

Signály jsou podobné přerušením , rozdíl je v tom, že přerušení jsou zprostředkována CPU a zpracovávána jádrem, zatímco signály jsou zprostředkovány jádrem (možná prostřednictvím systémových volání) a zpracovávány jednotlivými procesy . Jádro může předat přerušení jako signál procesu, který jej způsobil (typickými příklady jsou SIGSEGV , SIGBUS , SIGILL a SIGFPE ).

Dějiny

Verze 1 Unix měla samostatná systémová volání k zachycení přerušení, ukončení a zachycení stroje. Verze 4 spojila všechny pasti do jednoho hovoru, signálu a každá očíslovaná past dostala ve verzi 7 symbolické jméno . kill se objevil ve verzi 2 a ve verzi 5 mohl vysílat libovolné signály. Plán 9 od Bell Labs nahradil signály poznámkami , které umožňují odesílání krátkých, libovolných řetězců.

Odesílání signálů

Kill (2) Systémové volání vyšle určený signál na konkrétní proces, je-li oprávnění povolit. Podobně příkaz kill (1) umožňuje uživateli posílat signály do procesů. Funkce knihovny raise (3) posílá zadaný signál aktuálnímu procesu.

Výjimky, jako je dělení nulou nebo narušení segmentace, budou generovat signály (zde SIGFPE „výjimka s pohyblivou řádovou čárkou“ a SIGSEGV „narušení segmentace“, které ve výchozím nastavení způsobují jádrový výpis a ukončení programu).

Jádro může generovat signály k upozornění procesů na události. Například SIGPIPE bude generováno, když proces zapisuje do kanálu, který byl zavřen čtečkou; ve výchozím nastavení to způsobí ukončení procesu, což je výhodné při konstrukci shell kanálů .

Zadání určitých kombinací kláves na řídicí terminál běžícího procesu způsobí, že mu systém pošle určité signály:

  • Ctrl-C (ve starších Unixech DEL) vysílá signál INT („přerušení“, SIGINT ); ve výchozím nastavení to způsobí ukončení procesu.
  • Ctrl-Z vysílá signál TSTP („koncová zastávka“, SIGTSTP ); ve výchozím nastavení to způsobí, že proces pozastaví provádění.
  • Ctrl- \ odešle QUIT signál ( SIGQUIT ); ve výchozím nastavení to způsobí ukončení procesu a vypsání jádra.
  • Ctrl-T (není podporováno ve všech UNIXech) odesílá INFO signál ( SIGINFO ); ve výchozím nastavení, a pokud to příkaz podporuje, způsobí to, že operační systém zobrazí informace o spuštěném příkazu.

Tyto výchozí kombinace kláves s moderními operačními systémy lze změnit pomocí příkazu stty .

Zpracování signálů

Manipulátory signálu lze nainstalovat pomocí systémového volání signal (2) nebo sigaction (2) . Pokud není pro určitý signál nainstalován obslužný program signálu, použije se výchozí obslužný program. Jinak je signál zachycen a je vyvolán obslužný program signálu. Proces může také určit dvě výchozí chování bez vytvoření obslužné rutiny: ignorujte signál (SIG_IGN) a použijte výchozí obslužný program signálu (SIG_DFL). Existují dva signály, které nelze zachytit a zpracovat: SIGKILL a SIGSTOP .

Rizika

Zpracování signálu je citlivé na závodní podmínky . Protože jsou signály asynchronní, může být do procesu během provádění rutiny zpracování signálu dodán další signál (dokonce stejného typu).

Sigprocmask (2) volání může být použit k zablokování a odblokování dodávání signálů. Blokované signály nejsou do procesu doručovány, dokud nejsou odblokovány. Signály, které nelze ignorovat (SIGKILL a SIGSTOP), nelze blokovat.

Signály mohou způsobit přerušení probíhajícího systémového volání a ponechat aplikaci na správě netransparentního restartu .

Obslužné rutiny signálu by měly být psány způsobem, který nevede k žádným nežádoucím vedlejším účinkům, např. Ke změně chyb, změně masky signálu, změně dispozice signálu a dalším globálním změnám atributů procesu . Nebezpečné není ani používání nereentrantních funkcí, např. Malloc nebo printf , uvnitř obsluh signálů. Specifikace POSIX a signál manuálové stránky Linuxu (7) zejména vyžadují, aby všechny systémové funkce přímo nebo nepřímo volané ze signální funkce byly bezpečné pro asynchronní signál . Signálu bezpečnostní (7) man stránka obsahuje seznam organizací, jako asynchronní signálem funkce bezpečný systém (prakticky systémových volání ), v opačném případě se jedná o nedefinované chování . Doporučuje se jednoduše nastavit nějakou volatile sig_atomic_tproměnnou v obsluze signálu a otestovat ji jinde.

Obsluha signálu může místo toho umístit signál do fronty a okamžitě se vrátit. Hlavní vlákno pak bude pokračovat „nepřerušeně“, dokud nebudou signály odebírány z fronty, například ve smyčce událostí . „Nepřerušený“ zde znamená, že operace, které blokují, se mohou předčasně vrátit a musí být obnoveny , jak je uvedeno výše. Signály by měly být zpracovávány z fronty v hlavním vlákně, a nikoli pracovními fondy , protože to znovu zavádí problém asynchronicity. Správa fronty však není možná bezpečným způsobem asynchronního signálu pouze se sig_atomic_t , protože pouze jednotlivá čtení a zápisy do těchto proměnných jsou zaručeny atomové, nikoli přírůstky nebo (načítání a) dekódování, jak by bylo požadováno pro fronta. Ve skutečnosti lze tedy pouze jeden signál na handler bezpečně zařadit do fronty pomocí sig_atomic_t, dokud nebude zpracován.

Vztah s hardwarovými výjimkami

Provádění procesu může mít za následek generování hardwarové výjimky , například pokud se proces pokusí dělit nulou nebo dojde k chybě stránky .

V operačních systémech podobných Unixu tato událost automaticky změní kontext procesoru a spustí se zpracování obslužné rutiny výjimky jádra . V případě některých výjimek, jako je například chyba stránky , má jádro dostatečné informace, aby plně zvládlo samotnou událost a obnovilo provádění procesu.

Jiné výjimky však jádro nemůže zpracovávat inteligentně a místo toho musí operaci zpracování výjimek odložit na chybující proces. Tohoto odložení je dosaženo prostřednictvím signálního mechanismu, kde jádro vysílá do procesu signál odpovídající aktuální výjimce. Pokud by se například proces pokusil o celočíselné dělení nulou na CPU x86 , vygenerovala by se výjimka chyby dělení a jádro by do procesu poslalo signál SIGFPE .

Podobně, pokud by se proces pokusil získat přístup k adrese paměti mimo svůj virtuální adresní prostor , jádro by proces upozornilo na toto narušení signálem SIGSEGV . Přesné mapování mezi názvy signálů a výjimkami je samozřejmě závislé na CPU, protože typy výjimek se mezi architekturami liší.

Signály POSIX

Níže uvedený seznam dokumentuje signály uvedené ve specifikaci Single Unix . Všechny signály jsou v souboru <signal.h>záhlaví definovány jako makro konstanty . Název makro konstanty se skládá z předpony „SIG“ následované mnemotechnickým názvem signálu.

SIGABRT aSIGIOT
Signál SIGABRT a SIGIOT je odeslán do procesu, aby mu řekl, že má přerušit , tj. Ukončit . Signál je obvykle iniciován samotným procesem, když volá abort()funkci standardní knihovny C , ale může být odeslán do procesu zvenčí jako jakýkoli jiný signál.
SIGALRM ,SIGVTALRM aSIGPROF
Signál SIGALRM, SIGVTALRM a SIGPROF je odeslán do procesu, když uplyne časový limit specifikovaný ve volání na předchozí funkci nastavení alarmu (například setitimer). SIGALRM je odeslán po uplynutí reálného nebo hodinového času. SIGVTALRM je odeslán, když vyprší čas CPU použitý procesem. SIGPROF se odešle, když uplyne čas procesoru používaný procesem a systémem jménem procesu.
SIGBUS
SIGBUS signál je poslán do procesu, kdy to způsobuje chyby sběrnice . Podmínky, které vedou k odesílání signálu, jsou například nesprávné zarovnání přístupu do paměti nebo neexistující fyzická adresa.
SIGCHLD
Signál SIGCHLD je odeslán do procesu, když podřízený proces skončí , je přerušen nebo se po přerušení obnoví. Jedním z běžných použití signálu je dát operačnímu systému pokyn vyčistit prostředky používané podřízeným procesem po jeho ukončení bez výslovného volání waitsystémového volání.
SIGCONT
Signál SIGCONT dává operačnímu systému pokyn, aby pokračoval (restartoval) proces dříve pozastavený signálem SIGSTOP nebo SIGTSTP. Jedním z důležitých použití tohoto signálu je řízení úloh v prostředí Unix .
SIGFPE
Signál SIGFPE je odeslán do procesu, pokud byla v hardwaru s plovoucí desetinnou čárkou nebo celočíselným aritmetickým hardwarem detekována výjimečná (ale ne nutně chybná) podmínka. To může zahrnovat dělení nulou , přetečení s plovoucí desetinnou čárkou nebo přetečení, přetečení celého čísla, neplatnou operaci nebo nepřesný výpočet. Chování se může lišit v závislosti na hardwaru.
PŘIPOJENÍ
Signál SIGHUP je odeslán do procesu, když je jeho ovládací terminál zavřený. Původně byl navržen tak, aby upozornil na proces poklesu sériové linky ( zavěšení ). V moderních systémech tento signál obvykle znamená, že řídicí pseudo nebo virtuální terminál byl uzavřen. Mnoho démonů (kteří nemají žádný řídící terminál) interpretuje příjem tohoto signálu jako požadavek na opětovné načtení konfiguračních souborů a vyprázdnění/opětovné otevření souborů protokolu namísto ukončení. nohup je příkaz, který zajistí, aby příkaz ignoroval signál.
SIGILL
Signál SIGILL je odeslán do procesu, když se pokusí provést nezákonnou , nesprávně formátovanou, neznámou nebo privilegovanou instrukci .
SIGINT
Signál SIGINT je odeslán do procesu jeho řídícím terminálem, když si uživatel přeje proces přerušit . Obvykle se to spouští stisknutím Ctrl+C , ale v některých systémech lze použít znak „ odstranit “ nebo „ konec “.
SIGKILL
Signál SIGKILL je odeslán do procesu, aby způsobil jeho okamžité ukončení ( zabití ). Na rozdíl od SIGTERM a SIGINT nelze tento signál zachytit ani ignorovat a přijímací proces nemůže po přijetí tohoto signálu provést žádné vyčištění. Platí následující výjimky:
  • Zombie procesy nelze zabít, protože jsou již mrtvé a čekají, až je jejich nadřazené procesy sklidí.
  • Procesy, které jsou v zablokovaném stavu, nezemřou, dokud se znovu neprobudí.
  • Proces init je speciální: Nedostává signály, které nechce zpracovat, a proto může ignorovat SIGKILL. Výjimkou z tohoto pravidla je, když je init ptraced na Linuxu.
  • Proces nepřerušitelného spánku nemusí být ukončen (a uvolnit jeho zdroje), i když byl odeslán SIGKILL. Toto je jeden z mála případů, kdy může být nutné restartovat systém UNIX, aby se vyřešil dočasný problém se softwarem.
SIGKILL se používá jako poslední možnost při ukončování procesů ve většině procedurách vypnutí systému, pokud v reakci na SIGTERM nedojde k dobrovolnému ukončení. Aby se urychlil postup vypínání počítače, Mac OS X 10.6, neboli Snow Leopard , odešle SIGKILL do aplikací, které se označily jako „čisté“, což má za následek rychlejší časy vypínání s pravděpodobně bez škodlivých účinků. Příkaz killall -9má podobný, i když nebezpečný účinek, když je proveden např. V Linuxu; neumožňuje programům ukládat neuložená data. Má další možnosti a bez použití bezpečnějšího signálu SIGTERM.
SIGPIPE
Signál SIGPIPE je odeslán do procesu, když se pokouší zapsat do kanálu bez procesu připojeného k druhému konci.
SIGPOLL
Signál SIGPOLL je odeslán, když došlo k události na explicitně sledovaném deskriptoru souboru. Efektivní použití vede k vytváření asynchronních požadavků I/O, protože jádro bude dotazovat deskriptor místo volajícího. Poskytuje alternativu k aktivnímu hlasování .
PŘIHLASTE se doSIGRTMAX
Signály SIGRTMIN až SIGRTMAX jsou určeny k použití pro účely definované uživatelem. Jsou to signály v reálném čase .
SIGQUIT
Signál SIGQUIT je odeslán do procesu jeho řídícím terminálem, když uživatel požaduje, aby proces skončil a provedl jádrový výpis .
SIGSEGV
SIGSEGV signál je poslán do procesu, kdy to dělá neplatný odkaz virtuální paměť, nebo segmentace poruch , tedy když provádí seg mentace v iolation .
SIGSTOP
Signál SIGSTOP instruuje operační systém, aby zastavil proces pro pozdější obnovení.
SIGSYS
Signál SIGSYS je odeslán do procesu, když předá špatný argument systémovému volání . V praxi se s tímto druhem signálu setkáváme jen zřídka, protože aplikace se při volání spoléhají na knihovny (např. Libc ). SIGSYS mohou přijímat aplikace porušující bezpečnostní pravidla Linux Seccomp nakonfigurovaná tak, aby je omezovala. SIGSYS lze také použít k emulaci cizích systémových volání, např. Emulace systémových volání Windows na Linuxu.
SIGTERM
Signál SIGTERM je odeslán do procesu, aby požádal o jeho ukončení . Na rozdíl od signálu SIGKILL může být procesem zachycen a interpretován nebo ignorován. To umožňuje, aby proces provedl pěkné ukončení, uvolnění zdrojů a uložení stavu, je -li to vhodné. SIGINT je téměř identický s SIGTERM.
SIGTSTP
SIGTSTP signál je poslán do procesu její ovládající terminálem jej požádat o doraz ( t erminal st o p ). Obvykle jej spouští uživatel stisknutím tlačítka Ctrl+Z . Na rozdíl od SIGSTOP může proces zaregistrovat zpracovatel signálu pro signál nebo jej ignorovat.
SIGTTIN aSIGTTOU
Tyto SIGTTIN a SIGTTOU signály jsou odesílány do procesu, když se pokusí přečíst v či psát ven , respektive od tty , zatímco v pozadí . Tyto signály jsou obvykle přijímány pouze procesy pod kontrolou úlohy ; démoni nemají ovládací terminály, a proto by nikdy neměli přijímat tyto signály.
SIGTRAP
Signál SIGTRAP je odeslán do procesu, když dojde k výjimce (nebo pasti ): podmínka, o kterou debugger požádal, aby byl informován - například když je spuštěna konkrétní funkce nebo když konkrétní proměnná změní hodnotu.
SIGURG
Signál SIGURG je odeslán do procesu, když má zásuvka k dispozici naléhavá nebo mimopásmová data ke čtení.
SIGUSR1 aSIGUSR2
Signály SIGUSR1 a SIGUSR2 jsou odesílány do procesu, který indikuje uživatelem definované podmínky .
SIGXCPU
Signál SIGXCPU je odeslán do procesu, když vyčerpal CPU na dobu, která překračuje určitou předem stanovenou uživatelem nastavitelnou hodnotu. Příchod signálu SIGXCPU poskytuje přijímacímu procesu šanci rychle uložit všechny mezivýsledky a elegantně ukončit, než jej operační systém ukončí pomocí signálu SIGKILL.
SIGXFSZ
Signál SIGXFSZ je odeslán do procesu, když roste soubor, který překračuje maximální povolenou velikost .
SIGWINCH
Signál SIGWINCH je odeslán do procesu, když jeho ovládací terminál změní svou velikost ( výhra dow ch ange).

Výchozí akce

Proces může definovat, jak zacházet s příchozími signály POSIX . Pokud proces nedefinuje chování pro signál, použije se výchozí obsluha pro tento signál. Níže uvedená tabulka uvádí některé výchozí akce pro systémy UNIX kompatibilní s POSIX, jako jsou FreeBSD , OpenBSD a Linux .

Signál Přenosné
číslo
Výchozí akce Popis
SIGABRT 6 Ukončit (core dump) Zpracovat signál přerušení
SIGALRM 14 Vypovědět Budík
SIGBUS N/A Ukončit (core dump) Přístup k nedefinované části paměťového objektu
SIGCHLD N/A Ignorovat Podřízený proces byl ukončen, zastaven nebo pokračoval
SIGCONT N/A Pokračovat Pokud je zastaveno, pokračujte v provádění
SIGFPE 8 Ukončit (core dump) Chybná aritmetická operace
PŘIPOJENÍ 1 Vypovědět Zavěsit
SIGILL 4 Ukončit (core dump) Nelegální instrukce
SIGINT 2 Vypovědět Signál přerušení terminálu
SIGKILL 9 Vypovědět Zabít (nelze chytit ani ignorovat)
SIGPIPE 13 Vypovědět Pište na dýmku, aby ji nikdo nečetl
SIGPOLL N/A Vypovědět Pollable event
SIGPROF N/A Vypovědět Profilovací časovač vypršel
SIGQUIT 3 Ukončit (core dump) Koncový signál ukončení
SIGSEGV 11 Ukončit (core dump) Neplatný odkaz na paměť
SIGSTOP N/A Stop Zastavit spouštění (nelze chytit ani ignorovat)
SIGSYS N/A Ukončit (core dump) Špatné systémové volání
SIGTERM 15 Vypovědět Ukončovací signál
SIGTRAP 5 Ukončit (core dump) Trasovací/zarážkový past
SIGTSTP N/A Stop Koncový signál zastavení
SIGTTIN N/A Stop Proces na pozadí při pokusu o čtení
SIGTTOU N/A Stop Proces na pozadí při pokusu o zápis
SIGUSR1 N/A Vypovědět Uživatelsky definovaný signál 1
SIGUSR2 N/A Vypovědět Uživatelsky definovaný signál 2
SIGURG N/A Ignorovat Data mimo pásmo jsou k dispozici na soketu
SIGVTALRM N/A Vypovědět Platnost virtuálního časovače vypršela
SIGXCPU N/A Ukončit (core dump) Překročen časový limit CPU
SIGXFSZ N/A Ukončit (core dump) Překročen limit velikosti souboru
SIGWINCH N/A Ignorovat Velikost okna terminálu se změnila
Přenosné číslo:
Pro většinu signálů je odpovídající číslo signálu definováno implementací. Tento sloupec uvádí čísla uvedená ve standardu POSIX.
Vysvětlené akce:
Ukončit  - Abnormální ukončení procesu. Proces je ukončen se všemi důsledky _exit () kromě toho, že stav zpřístupněný pro wait () a waitpid () označuje abnormální ukončení zadaným signálem.
Ukončit (core dump)  - Abnormální ukončení procesu. Kromě toho může dojít k implementaci abnormálních akcí ukončení, jako je vytvoření základního souboru.
Ignorovat  - signál bude ignorován.
Zastavit  - zastaví (nikoli ukončí) proces.
Pokračovat  - Pokud je proces zastaven, bude pokračovat; v opačném případě signál ignorujte.

Různé signály

Následující signály nejsou specifikovány ve specifikaci POSIX . Někdy se však používají v různých systémech.

SIGEMT
Signál SIGEMT je odeslán do procesu, když dojde k zachycení emulátoru .
SIGINFO
Signál SIGINFO je odeslán do procesu, když je z řídicího terminálu přijat požadavek na stav ( info ).
SIGPWR
Signál SIGPWR je odeslán do procesu, když v systému dojde k výpadku napájení .
SIGLOST
Signál SIGLOST je odeslán do procesu při ztrátě zámku souboru .
SIGSTKFLT
Signál SIGSTKFLT je odeslán do procesu, když koprocesor zažije st ac k f au lt (tj. Vyskočí, když je zásobník prázdný, nebo tlačí, když je plný). To je definováno, které však nebyly využity na Linuxu, kde X87 bude koprocesor stohu chyba generovat SIGFPE místo.
PODPISOVÁNO
Signál SIGUNUSED je odeslán do procesu při uskutečnění systémového volání s nepoužívaným číslem systémového volání. Je synonymem pro SIGSYS ve většině architektur.
SIGCLD
Signál SIGCLD je synonymem pro SIGCHLD.

Viz také

Reference

externí odkazy