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

Č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.2.2015 7:20 /MaReK Olšavský
Svobodný databázový projekt RethinkDB není klasickou RDBMS, pro ukládání JSON dokumentů. Na stránkách Opensource.com vyšel rozhovor s Slavou Akhmechetem, zakladatelem RethinkDB.
Přidat komentář

27.2.2015 7:20 /MaReK Olšavský
Intel zjednodušil značení Atomů určených pro mobilní zařícení. Když uživatel uvidí Atom x3 a Atom x7 v popisu zařízení, napoví mu to více o výkonu, než stávající číselné značení (Z3570, Z3770).
Přidat komentář

26.2.2015 7:25 /MaReK Olšavský
Úspěšný výrobce ARM SoC Allwinner významně porušuje GPL „rabováním“ zdrojových kódů.
Přidat komentář

24.2.2015 7:15 /MaReK Olšavský
Blížící se Cinnamon 2.6 bude výrazným skokem kupředu zejména z pohledu uživatelů vícemonitorových sestav, případně oceníte lepší chování „multimediálních kláves“.
Přidat komentář

24.2.2015 7:15 /MaReK Olšavský
Neobvyklý počet 100 ARM jader (64 bitových) by měl nabídnout nový mikroprocesor EZchip. Izraelská společnost jím míří do míst, kde je potřeba vysoký výkon. BTW: U RedHatu se také pilně pracuje na podpoře 64 bitového ARMu.
Přidat komentář

19.2.2015 7:20 /MaReK Olšavský
Příznivci leteckých simulátorů se mohou zaradovat, vyšel FlightGear 3.4. Vylepšila se práce s pamětí, přibyla drobná vylepšení grafiky, nebo nová letadla. Uršitě bude brzo v repozitářích distribucí, ale nákup na e-shopu si určitě vývojáři zaslouží.
Přidat komentář

19.2.2015 7:20 /MaReK Olšavský
Další ohlášení konce se týká projektu m0n0wall, jehož vývojáři dělali distribuci FreeBSD pro nasazení jako firewallu. Můžeme čekat podobný osud, jako u Bodhi Linuxu, nebo #!, jež byly záhy reinkarnovány?
Přidat komentář

18.2.2015 6:57 /MaReK Olšavský
Minimalistická distribuce s desktopem Enlightenment (E19) se má čile k životu, po reinkarnaci, a vydání Bodhi Linuxu 3.0.0 je k dispozici uživatelům. Vedle vydání pro „běžná PC“ vyšla verze i pro staré systémy a Chromebooky. Bohužel zatím nepřevzali z Ubuntu způsob povýšení na novou verzi a tak uživatelé starší verze musí upgradovat reinstalací.
Přidat komentář

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

> Poslední diskuze

2.2.2015 6:40 / MaReK Olšavský
Re: Churchill

30.1.2015 13:16 / Petr Ježek
Churchill

27.1.2015 12:58 / Ladislav Kulatý
Re: Mazání adřářů v linuxu pro IP kamery

26.1.2015 23:57 / Sinuhed
Re: Mazání adřářů v linuxu pro IP kamery

26.1.2015 11:05 / Sinuhed
Re: Mazání adřářů v linuxu pro IP kamery

Více ...

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