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 12032×

Č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ů

24.10.2014 17:45 /Petr Ježek
Hyper-Z pro radeony se vrací. Anreas Böll vydal patch umožňující opětovné povolení Hyper-Z v aktuální mesa 10.3 pro radeon R600g a radeonsi. Doporučuje se aplikovat, testovat a reportovat případné problémy před vydáním mesa10.4 v prosinci.
Komentářů: 1

24.10.2014 7:33 /MaReK Olšavský
Vyšlo Ubuntu 14.10 a spiny s dalšími desktopy Kubuntu 14.10, Xubuntu 14.10 a poprvé i Ubuntu-Mate (Lubuntu 14.10 bude opožděno). Změn je poměrně málo, nestihli zařadit aktuální GNOME a je bez convergence části.
Přidat komentář

24.10.2014 7:33 /MaReK Olšavský
Přípravy na vydání Debianu 8 jsou v plném proudu a nejednoho potenciálního uživatele by mohla zajímat připravovaná podpora multimédií pro novou verzi (jinak dosti konzervativní distribuce). Asi nebude potřeba používat obskurdní repozitáře kvůli podpoře přehrávání audia/videa a hudebníky nejspíše také potěší.
Přidat komentář

23.10.2014 7:13 /MaReK Olšavský
CERN používá OpenStack přibližně rok. Jaké je aktuální používání při výzkumu ukazuje článek na OpenSource.com. Vyprodukovaných dat, z měření, není malé množství a pro jejich zpracování je potřebný výkon několikatisíců serverů a pracovních stanic.
Přidat komentář

23.10.2014 7:13 /MaReK Olšavský
Prodejce starších her; jež jsou často hratelnější, než moderní grafické orgie; Good Old Games dosáhl milníku 100 her připravených pro Linux (nejde o portace, ale připravené konfigurace DOSBoxu/Wine).
Přidat komentář

23.10.2014 7:13 /MaReK Olšavský
O malou reklamu pro Ubuntu se postaral Andy Swan, se svým laptopem, při analýze počasí pro tragickou Velkou Cenu Japonska 2014 (Formule 1).
Přidat komentář

22.10.2014 7:19 /MaReK Olšavský
Programovacímu jazyku Swift, jenž nedávno zveřejnil Apple a je uzavřený, vzniká svobodná odpověď Phoenix (repozitář). Jazyk bude stejný, takže lze očekávat, že se Apple bude bránit i soudně. Název Phoenix už nejspíše také někdo používá, starší pamatují, že se tak chvíli jmenoval dnešní Mozilla Firefox.
Přidat komentář

22.10.2014 7:19 /MaReK Olšavský
Programátorům v PHP je určen nástroj RIPS, který jim pomůže odhalit zranitelnosti v jejich kódu. Pokud znáte další nástroje, podělte se o ně v diskusi.
Přidat komentář

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

> Poslední diskuze

24.10.2014 17:47 / Petr Ježek
Andreas

16.10.2014 7:56 / Leo
Sanba

13.10.2014 7:20 / MaReK Olšavský
Re: PDF a podpis

10.10.2014 8:01 / Hynek Beran
PDF a podpis

10.10.2014 7:41 / Dusan Hlavac
Re: Takže nic.

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