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

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

1.9.2014 6:55 /MaReK Olšavský
Lennart Poettering, známý díky práci na PulseAudio a systemd, sepsal svou vizi sestavení software v distribuci. Rád by viděl pohromadě systemd, btrfs, nebo sjednocení uspořádání adresářů knihoven napříč distribucemi a hlavně vysokou míru zabezpečení.
Přidat komentář

1.9.2014 6:55 /MaReK Olšavský
Vyšlo 88. číslo Full Circle Magazine (pdf, ePub). Měsíčník, nejen pro uživatele *Ubuntu, obsahuje články o ripování DVD pomocí Handdrake, vlastní kompilaci jádra a pravidelné seriály.
Přidat komentář

1.9.2014 6:55 /MaReK Olšavský
Javascriptová/CSS knihovna YUI zůstane dalšího vývoje od Yahoo. Yahoo ukončuje vývoj, protože rozsáhlý YUI ztrácí na poularitě. Pokud bude vývoj pokračovat v nezávislé komunitě, nebude se muset framework přejmenovat?
Přidat komentář

29.8.2014 7:11 /MaReK Olšavský
Vývojáři webových aplikací v PHP získají s novým PHP 5.6 i novou komponentu phpdbg pro ladění aplikací. Celý seznam novinek podrobně rozebírá migrační příručka.
Přidat komentář

29.8.2014 7:11 /MaReK Olšavský
Populární Raspberry Pi má dalšího konkurenta, avšak nový minipočítač Creator CI20 nevyužívá mikroprocesor rodin ARM a x86, nýbrž MIPS32. Zatím je k dispozici pouze vývojářům.
Přidat komentář

29.8.2014 7:11 /MaReK Olšavský
Red Hat opouští CTO Brian Stevens, jenž do RH přišel v roce 2001 z DECu.
Přidat komentář

28.8.2014 6:46 /MaReK Olšavský
Superpočítač za US$ 99, to je Parallella, jejíž vývojáři uspěli s kampaní na Kickstarteru před 18 měsíci. Co předcházelo uvedení na trh shrnuje článek Andrewa Backa. Otevřená platforma pro paralelní výpočty neznamená „jen“ vývoj hardware, ale i napsání SDK.
Přidat komentář

28.8.2014 6:46 /MaReK Olšavský
Zajímavá je historie Motoroly, jež byla průkopníkem mobilních telefonů, ale známá byla i díky mikroprocesorům, jež jsme měli v Amigách/Atari ST, nebo byly v prvních počítačích SUN Microsystems.
Přidat komentář

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

> Poslední diskuze

29.8.2014 14:31 / viperDavid
Re: Python s Lighttpd

27.8.2014 12:45 / Marek Pszczolka
LinuxMarket

27.8.2014 11:19 / Jan Němec
To je hlod

25.8.2014 16:20 / Aleš Hakl
Re: Kdyby autoři BeoSu nebyli blbci

24.8.2014 22:32 / Atrament
Překlep v 'properties'

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