LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (51) - Signály

Perl Tímto dílem začíná blok několika článků, které se budou věnovat vztahu s operačním systémem. První z nich má čtenáře seznámit s možnostmi při zpracovávání signálů.

29.1.2007 06:00 | Jiří Václavík | Články autora | přečteno 12123×

Čas od času nastane situace, kdy operační systém potřebuje programu předat nějaký příkaz. Takovému příkazu budeme říkat signál. V následujících odstavcích se budeme zabývat otázkami jak na ně reagovat a jak je vyvolávat.

Typickým příkladem vyvolání signálu je přerušení programu stisknutím Ctrl-c. V takovém případě je programu předán signál INT (zkratka od interrupt) a ten na to nějakým způsobem zareaguje. Obvykle se program ukončí, ale lze to ovlivnit.

Reakce na signály

Jak již víme, Perl umožňuje na signály vlastním způsobem reagovat. Funguje to tak, že se určí podprogram, který se má při obdržení signálu provést.

Odkazy na tyto podprogramy jsou obsaženy ve speciální proměnné %SIG. Klíči tohoto hashe jsou jména signálů a hodnotami odkazy na podprogramy, které mají být v případě obdržení odpovídajícího signálu volány.

Pro demonstrační účely si vytvoříme program, který zareaguje na INT signál. Měli bychom vymyslet takový program, který hned neskončí - aby bylo možné stisknutí Ctrl-C (nebo jiný způsob vyvolání) stihnout. To znamená použít například čtení ze zdroje dat. Takovým vhodným programem může být toto.

<> while 1;

Nyní v tomto programu vytvoříme akci pro signál INT - přiřadíme odkaz na podprogram do prvku hashe %SIG s příslušným klíčem.

$SIG{"INT"} = \&ctrl_c;

A nakonec musíme definovat proceduru ctrl_c. Celý program teď vypadá takto:

$SIG{"INT"} = \&ctrl_c;
<> while 1;
sub ctrl_c {
    print "Zachyceno Ctrl-c!\n";
}

Samozřejmě, že lze do prvků hashe %SIG přiřadit přímo anonymní podprogram vytvořený pomocí sub.

$SIG{"INT"} = sub {print "Zachyceno Ctrl-c!\n";};

Dodejme ještě, že řádek

$SIG{"INT"} = \&ctrl_c;

by se měl nacházet na začátku programu. Signály lze totiž zachytávat až od okamžíku, kdy je proměnná %SIG nastavena.

Nyní ale už zkusme spustit posledně vytvořený program. Tučně je zvýrazněn vstup včetně neviditelných kláves.

$ perl signal.pl [ENTER]
nejaky vstup[ENTER]
dalsi vstup[ENTER]
[CTRL-C]Zachyceno Ctrl-c!
[CTRL-C]Zachyceno Ctrl-c!
[CTRL-C]Zachyceno Ctrl-c!
[ENTER]
[CTRL-C]Zachyceno Ctrl-c!
[ENTER]
[CTRL-C]Zachyceno Ctrl-c!
[ENTER]
[ENTER]
...

Program touto cestou nelze ukončit. Aby to šlo, museli bychom jinak napsat podprogram ctrl_c - tedy použít funkci die.

Jména signálů jsou vzestupně uloženy v proměnné $Config{"sig_name"}, která je exportovaná ze standartního modulu Config. Všechny dostupné signály i s příslušnými čísly tak vypíše tento program.

use Config;
@signaly = split(" ", $Config{"sig_name"});
for ($i=0; $i<@signaly; $i++){
    print "Signal $i: ", $signaly[$i], "\n";
}

Do prvků hashe %SIG lze přiřadit místo odkazů na podprogramy i následující speciální řetězce.

ŘetězecReakce na vybraný signál
"IGNORE"obdržený signál se ignoruje
"DEFAULT"nastavuje zpět implicitní reakci na signál

Na závěr poznamenejme, že některé signály zachytit nelze (KILL, STOP).

Vyvolávání signálů

Funkce kill posílá signál danému procesu. kill přijímá 2 parametry - číslo nebo jméno signálu a seznam procesů, kterým se tento signál má poslat.

Podívejme se na několik ukázkových příkazů. Protože máme k dispozici proměnnou $$, která uchovává ID procesu, se kterým program běží, názorným příkladem může být sebevražda programu. Pošleme našemu programu signál KILL.

kill "KILL", $$;

Jak je patrné z výstupu programu, který nám vypsal seznam signálů, KILL má číslo 9. Tudíž stejný smysl bude mít tento příkaz.

kill 9, $$;

Často je u příkazu kill vidět, že se čárka nahrazuje šipkou =>, která má stejný význam.

kill "KILL" => $$;

Funkce getppid vrací PID rodičovského procesu. Tímto způsobem zabijeme shell.

kill "KILL" => getppid;

Upozorněme také návratovou hodnotu funkce kill. V případě, že se signál podařilo poslat, vrací funkce pravdivou hodnotu, v opačném případě nepravdivou. Příčinou toho může být například to, že nemáme dostatečná práva nebo prostě proces neexistuje - důvod pak už snadno zjistíme z proměnné $!. Dále v této souvislosti ještě zmiňme signál ZERO, který nedělá nic. Právě pomocí něj lze snadno testovat, zda nějaký proces existuje.

print "proces vypadá mrtvě ($!)" unless kill "ZERO" => 5032;

Pragma sigtrap

Modul sigtrap nabízí speciální rozhraní pro práci se signály. Zavádí se tímto způsobem.

use sigtrap qw(ovladač seznam_signálů);

Vše je o tom, že na signály ze seznamu signálů je aplikován ovladač, který určuje, jak na ně zareagovat. Proto jen stručně. Jako ovladač může být uveden jeden z následujících. V posledním případě je vlastní_ovladač cokoliv, co by šlo přiřadit jako hodnota do prvku hashe %SIG.

  • stack-trace (implicitní hodnota) - vypíše zprávu na STDERR
  • die - ukončí se běh programu
  • handler vlastní_ovladač - vykoná činnost zadanou uživatelem

Seznam signálů je prostě seznam signálů. Lze ale používat i některé speciální hodnoty:

  • normal-signals - INT, HUP, PIPE, TERM
  • error-signals - ABRT, BUS, EMT, FPE, ILL, QUIT, SEGV, SYS, TRAP
  • old-interface-signals - ABRT, BUS, EMT, FPE, ILL, PIPE, QUIT, SEGV, SYS, TERM, TRAP

Není-li uveden seznam signálů, je automaticky použito old-interface-signals.

Budou následovat příklady programů, které zachytávají různé signály. K testovacím účelům bude vhodné programům posílat signály příkazem kill -SIGNÁL číslo_procesu. Například

$ kill -INT 10538

K zjištění PID programu bude nejjednodušší přímo do programu připsat tento řádek.

print "Číslo procesu: $$\n";

Program s následujícím řádkem reaguje na signály INT a TERM tak, že se ukončí.

use sigtrap qw(die INT TERM);

To samé, jen pro signály normal-signals - tedy INT, HUP, PIPE, TERM, platí pro tento řádek.

use sigtrap qw(die normal-signals);

Nakonec zachytíme signály INT, HUP, PIPE, TERM a to tak, že při obdržení některého z těchto signálů bude vypsán jeho název pomocí námi napsaného podprogramu.

use sigtrap "handler", \&signal, "normal-signals";

print "Číslo procesu: $$\n";#abychom věděli, kam posílat zkušební signály
<> while 1;

sub signal {
    my($signal) = @_;
    print "Zachycen SIG$signal!\n";
}

Z příkladů by mělo být jasné, jak zachytávání pomocí sigtrap funguje.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

27.11.2014 7:10 /MaReK Olšavský
Malý desktop s distribucí Ubuntu a použitelným dostatkem RAM, to vše se SoC rodiny Cortex-A9, představila začínající společnost „Imp“. Cena do US$ 200,— je příjemná a dnes už by měl takto „slabý“ počítač dostačovat běžným uživatelům.
Přidat komentář

27.11.2014 7:10 /MaReK Olšavský
Na MeetBSD California 2014 prezentoval Jordan Hubbard plány pro příštích 10 let, ve vývoji FreeBSD. Operuje se s pojmy BYOD, cloud, virtualizace. Po výrazné finanční injekci a nasazení na Sony PS4 to vypadá na oživení projektu, jehož svobodný předchůdce tu byl dříve, než dnešní GNU/Linux (který již není možné považovat za alternativní OS).
Přidat komentář

27.11.2014 7:10 /MaReK Olšavský
O rozdílech mezi prohlížeči Google Chrome a Chromium nemá hodně uživatelů jasno, často je Chromium popisováno jen slovy „otevřená verze Chrome“. Stručné vysvětlení ukáže, kolik toho je, co Google nechává jako uzavřené kódy, většinou jde o technologie, které sice smí používat, ale nesmí je zveřejnovat.
Přidat komentář

26.11.2014 7:10 /MaReK Olšavský
Vyšel fork FreeBSD, DragonglyBSD 4.0, který je pouze ve verzi x86-64 (a 32 bitová verze ani není naplánována), zvedá limit souběžně podporovaných procesorů na 256, nebo vylepšuje podporu OpenGL renderování.
Přidat komentář

24.11.2014 7:19 /MaReK Olšavský
O přízeň uživatelů kodeků se uchází 2 balíky, FFmpeg a Libav (který je forkem FFmpeg, vzniklým v roce 2011).Mainstreamové distribuce, jako Debian, Ubuntu, nebo Fedora, používají Libav, ale Ubuntu by se mělo vrátit k FFmpeg, počínaje verzí 15.04. Ubuntu tímto činí další krok, který je nezávislý na mateřské distribuci Debian.
Přidat komentář

24.11.2014 7:19 /MaReK Olšavský
Blíží se dlouhé zimní večery a Steam přichází s nabídkou simulátoru kozy :-) za příjemných 9,99 €, samozřejmě i ve verzi pro GNU/Linux. Kolik toho zvládne jedna koza sežrat a zničit?
Přidat komentář

21.11.2014 7:41 /MaReK Olšavský
Američtí uživatelé již to zjistili, když byl ve Firefoxu defaultní vyhledávač přenastaven na Yahoo, ale Google již není jediným partnerem pro vyhledávání (a financování).
Přidat komentář

20.11.2014 7:36 /MaReK Olšavský
Libby Clark sepsala, pro Linux Foundation, příběh zapojení SanDisku do vývoje F/L/OSS. SanDisk se postupně stal 7. největším přispěvatelem do vývoje Cephu.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

11.11.2014 14:24 / Libor Suchý
Nekonečný while cyklus

10.11.2014 19:09 / Libor Suchý
Re: tabulka - bitovy sucet

10.11.2014 19:03 / Libor Suchý
Re: tabulka - bitovy sucet

24.10.2014 17:47 / Petr Ježek
Andreas

16.10.2014 7:56 / Leo
Sanba

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2014) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze | zákony online