|
Signály
Vlastnosti,
funkcie, príklad, ...
Signál oznamuje procesu, že
došlo k nejakej udalosti. Signály sa niekedy rovnako nazývajú "programovými
prerušeniami". Signály sa obvykle objavujú
asynchrónne. To znamená, že
proces dopredu nevie, kedy signál sa objaví.
//---
Signály môžu
byť generované napríklad prerušením klávesnice, chybovými udalosťami, ...
//---
Zoznam
existujúcich signálov je možné získať príkazom kill -l z príkazového
interpreta.
//---
Základné
vlastnosti signálov
1) priorita signálov -
signály nemajú žiadnu vzájomnú prioritu. qqneexistuje
žiadny mechanizmus na určenie toho, ktorý signál sa
qoobslúži prvý, ak ich príde viac v tom
istom čase
2) obmedzenosť počtu signálov
- počet podporovaných signálov je qoobmedzený
na počet bitov slova procesora
3) spracovanie
signálov - signály môžu byť:
qiqiqi- zablokované -
bez ďalšieho spracovania
qiqiqi- nezablokované
- spracovávané:
qiqiqiqiqiqi- jadrom
qiqiqiqiqiqi- vlastnou
obsluhou
Výnimku spracovania signálov
tvoria iba signály SIGKILL a SIGSTOP, ktoré sa vždy musia
spracovávať jadrom OS.
//---
Signály môžu odosielať:
1) jeden
proces druhému alebo sám sebe
2) jadro
procesu
//---
Každý signál má svoj názov,
ktorý je určený v hlavičkovom súbore <signal.h>
//---
Základné funkcie pre prácu
so signálmi
1) Spracovanie
signálu - signal
Syntax:
typedef void (*sighandler_t)(int);
sighandler_t signal(int cislo_signalu, sighandler_t
spracovanie);
Popis:
Funkcia signal oznamuje jadru spôsob
spracovania signálu cislo_signalu pre
aktuálny proces Spôsob spracovania spracovanie signálu môže nadobúdať
nasledujúce hodnoty:
-
SIG_IGN - ignorovanie
signálu (bez ďalšieho spracovania)
-
SIG_DFL - spracovanie jadrom
-
smerník na funkciu - funkcia,
ktorá bude reagovať príchod signálu cislo_signalu
Návratovou
hodnotou je typ reakcie na tento signál pri jeho poslednom nastavení. V
niektorých OS sa môže stať, že po ukončení spracovania signálu sa spôsob
spracovania implicitne nastaví na hodnotu SIG_DFL.
Ak chceme, aby sa po každom príchode signálu spracovanie vykonávalo
volaním príslušnej funkcie, je potrebné ju registrovať znovu v rámci jej
tela.
2)
Poslanie signálu - kill
Syntax:
int kill (int pid, int sig)
Popis:
Pošle signál
sig nejakému procesu so zadaným
pid, alebo skupine procesov.
Toto závisí od
hodnoty pid následovne:
-
pid > 0 - signál
sig sa pošle príslušnému procesu
-
pid
= 0 - signál sig sa
pošle každému procesu v skupine aktuálneho
procesu
-
pid
=-1 - signál sig sa pošle každému procesu
okrem procesov s PID >
pid
-
pid <-1 -
signál sig sa pošle každému
procesu v skupine procesov s PID =-pid
3)
Pozastavenie procesu - pause
Syntax:
void pause (void)
Popis:
Funkcia
pause spôsobí pozastavenie procesu do doby
príchodu ľubovolného signálu. Pokračuje sa za príkazom
pause až po vykonaní spracovania signálu.
//---
Jednoduchý príklad
Vytvorte
synovský proces simulujúci budík. Nech rodičovský proces žiada budík -
synovský proces, aby ho ráno zobudil. Pošle synovskému procesu signál.
Synovský proces potvrdí, že ho zobudí. Pomocou funkcie
sleep sa odsimuluje noc. Potom nech synovský
proces pošle rodičovskému procesu signál, že je čas vstávať. Rodičovský
proces odpovie, že už vstáva.
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void synProc();
void otecProc();
void f1();
void f2();
int pid1,pid2;
main()
{
pid1=getpid();
switch (pid2=fork())
{
case -1: printf("Nevytvoril som proces");
break;
case 0: synProc();
break;
default: otecProc();
}
}
void otecProc()
{
printf("Chcem zobudit\n");
signal(SIGUSR1, f1);
kill(pid2,SIGUSR1);
pause();
}
void synProc()
{
signal(SIGUSR1,f2);
pause();
}
void f1()
{
printf("Uz vstavam!!!");
}
void f2()
{
printf("Akceptujem poziadavku\n");
sleep(1);
printf("Uz je cas vstavat!!!\n");
kill(pid1,SIGUSR1);
}
Pre komunikáciu
nám postačí jeden signál SIGUSR1. Rodičovský proces pošle
synovskému procesu signál a vykoná sa pause.
Synovský proces príjme signál. Po uplynutí noci spätne pošle signál
rodičovskému procesu. Rodič zareaguje na tento signál a vypíše, že už
vstáva.
//---
Ako a kedy sa
signály vysielajú?
Existuje 5 podmienok
generovania signálov.
1)
Volanie jadra
kill umožňuje procesu, aby odoslal signál
inému procesu alebo samému sebe. Označenie
kill je tu trochu zavádzajúce, pretože signál
zakaždým neukončí proces. Niektoré signály skutočne
prijímací proces ukončia, ale iné iba informujú proces o určitej podmienke,
ktorú potom prijímajúci proces spracuje.
int
kill (int pid, int sig)
Je zrejmé, že proces nemôže
odosielať signál ľubovolnému procesu. Pre odoslanie signálu je treba, aby
odosielajúci i prijímajúci proces mal totožné ID efektívneho užívateľa,
alebo musí byť odosielajúci superužívateľom.
Volanie jadra
kill vykonáva i mnohé ďalšie činnosti, ktoré
sú závislé na hodnote jeho argumentov.
- Ak je argument
pid nulový, signál je
odoslaný všetkým procesom v skupine odosielateľa
- Ak je argument
pid rovný -1 a odosielateľ nie je
superužívateľ, signál je odoslaný všetkým procesom, ktorých ID reálneho
užívateľa sa rovná ID efektívneho užívateľa odosielajúceho procesu
- Ak je argument
pid rovný -1 a odosielateľ je superužívateľ,
je signál odoslaný všetkým procesom okrem procesov systémových (predovšetkým
procesy s PID rovný 0 alebo1)
- Ak je argument
pid záporný, ale nie -1, signál je odoslaný
všetkým procesom, ktorých ID skupiny procesov sa rovná absolútnej hodnote
pid
- ak je argument
sig nulový, vykoná sa kontrola výskytu
chyby, ale signál sa neodošle. takto sa dá preveriť platnosť
premennej pid.
2)
Príkaz
kill sa rovnako používa k odoslaniu signálu. Tento príkaz je
vlastne programom, ktorý vezme svoje premenné z príkazového riadku a
prevedie volanie jadra kill, preto všetky
obmedzenia a možnosti, ktoré boli uvedené vyššie, platia i pre tento
príkaz.
3)
Signály sa taktiež generujú
niektorými terminálovými znakmi. Napríklad každý interaktívny terminál má
definovaný znak prerušenia a znak ukončenia. Znak prerušenia (obvykle CTRL
+ C alebo DELETE) ukončí proces, ktorý práve prebieha - vygeneruje signál
SIGINT. Znak ukončenia (ukončí bežiaci proces a
generuje obraz pamäti procesu (core image) - generuje signál SIGQUIT.
Obraz pamäti procesu môže potom byť využitý ladiacím programom pre
dodatočnú analýzu behu procesu. Pre znak prerušenia i znak ukončenia môžeme
použiť takmer všetky znaky dostupné na klávesnici terminálu.
Okrem týchto dvoch riadiacich
terminálových znakov poskytuje 4.3BSSD terminálový znak pre pozastavenie
procesu (CTRL + Z), ktorý okamžite generuje signál SIGTSTP, a
ponúka i znak pre pozastavenie s omeškaním (CTRL +
Y). Tento druhý znak generuje signál SIGTSTP až vtedy, keď proces
číta znak z klávesnice.
Tieto signály generované
terminálom sa neodosielajú len procesu, ktorý práve beží, ale všetkým
procesom v danej riadiacej skupine terminálu. Tieto signály väčšinou
odosiela procesom jadro.
4)
Rovnako
určité hardwareové stavy generujú signály. Napríklad kolízia aritmetiky
reálnych čísel generuje chybu SIGFPE. Ak dôjde k odkazu na adresu
mimo adresový priestor procesu, vygeneruje sa signál SIGSEGV.
Určité hardwareové stavy a signály, ktoré generujú,
sa môžu v jednotlivých prípadoch implementácií v Unixu líšiť. Tieto typy
signálov posiela väčšinou jadro procesu.
5)
Niektoré softwareové podmienky,
ktoré sú registrované jadrom, spôsobujú generovanie signálov. Napríklad
signál SIGURG je generovaný vtedy, keď do schránky príde informácia
prekročenia rozsahu dát (out-of-band-data).
//---
Čo môže
proces so signálom urobiť
1)
Proces môže byť vybavený
funkciou, ktorá sa volá, práve keď sa objaví určitý druh signálu. Táto
funkcia sa nazýva funkciou spracovania signálu a môže urobiť všetko, čo
proces vyžaduje, aby podmienku spracovala. Túto situáciu nazývame
zachytávanie signálov (catching).
2)
Proces a môže rozhodnúť, že
signál ignoruje. Môže ignorovať všetky signály okrem SIGKILL.
Signál SIGKILL je zvláštny tým, že dovoľuje správcovi systému, aby
ukončil akýkoľvek proces.
3)
Proces môže vykonať "implicitnú
činnosť". Proces býva väčšinou ukončený v okamžiku prijatia signálu,
niektoré signály generujú obraz pamäti procesu v jeho aktuálnom pracovnom
adresári.
//---
Spoľahlivé signály
Signály poskytované skoršími
verziami Unixu boli nespoľahlivé. Existovali určité situácie, kedy sa
signál mohol stratiť – objavila sa podmienka ku generovaniu signálu, ale
proces ju nezaregistroval. Ako v 4.3BSD, tak v Systému V boli prevedené
zmeny a systém už teraz poskytuje signály spoľahlivé. K zaisteniu väčšej
spoľahlivosti signálov boli prevedené tieto opatrenia:
-
funkcie spracovania signálov
zostanú nainštalované po objavení sa signálu. Skoršie verzie Unixu
prepísali činnosť spojenú so signálom na SIG_DFL tesne pred
volaním užívateľskej funkcie spracovania signálu. To znamenalo, že nový
výskyt toho istého signálu sa strácal predtým, než užívateľská funkcia
spracovania signál mohla znovu použiť volanie jadra signal.
-
Proces musí byť schopný
zábrániť výskytu určených signálov. My však nechceme, aby signál bol
zrušený (to môže učiniť pomocou SIG_IGN). Chceme, aby bol signál
zapamätaný a doručený, až na ňho budeme pripravený. V 4.3BSD s táto
činnosť nazýva blokovanie (blocking), v Systému
V je to podržanie (holding).
-
V priebehu predávania
signálov procesu je signál blokovaný (pozastavený). Tým je myslené to,
že pokiaľ je signál generovaný podruhé, zatiaľ čo proces spracováva jeho
prvý výskyt, nie je funkcia spracovania signálu volaná znovu. Namiesto
toho je druhý výskyt signálu zapamätaný. A až po normálnom návratu z funkcie
spracovania signálu je volaná znovu, aby spracovala zapamätaný signál.
//---
Prehľad signálov
SIGALRM
Proces si môže nastaviť alarm
(t.j. oznámenie o uplynutí časového kvanta pomocou volania jadra alarm.).
unsigned int alarm (unsigned int sec):
Arguments sec určuje počet sekúnd, ktoré uplynú predtým, než ma jadro
odoslať procesu signál SIGALRM. Argument určuje „reálny čas“
(nazývaný tiež „čas nástenných hodín“), nie čas CPU. Ak je premena rovná
nule, neruší sa žiadne predchádzajúce nastavenie alarmu procesu. Toto
volanie jadra sa používa k nastaveniu softwarového časového kvanta. Hodnota vrátená touto
funkciou predstavuje čas, ktorý prípadne ostáva z minulého volania
funkcie.
unsigned int sleep (unsigned int sec):
Funkcia sleep obvykle nastavuje signál SIGALRM, ktorý zachytí. Z
hľadiska interascie teito funkcie so signálom SIGALRM existuje
mnoho detailných podmienok, ktoré proces týmto stanovil, ale nimi sa
nehodláme zaoberať. Taktiež systém 4.3BSD nevracia hodnotu, zatiaľ čo
verzia System V vracajú množstvo nevyužitého času, pokiaľ bola funkcia
sleep ukončená predčasne potom, čo proces zachytil iný signál.
SIGBUS
Tento signál
sa generuje implementáciou závislou na chybách hardwaru.
SIGCLD
Tento signál je odoslaný
rodičovskému procesu, ak je ukončený detský proces. Na rozdiel od väčšiny
signálov uvedených na obr. 2.4 je tento signál ignorovaný, pokiaľ jej
proces nezachytí. V systému 4.3BSD tento signál taktiež ukazuje zmenu
stavu detského procesu. Nejedná sa iba o určenie smrti detského procesu.
Za zmenu stavu možno považovať smrť detského procesu alebo zastavenie
procesu prostredníctvom signálov SIGSTOP, SIGTTIN,
SIGTTOU alebo SIGTSTP. (Tento signál sa v 4.3BSD oficiálne
nazýva SIGCHLD. Názov SIGCLD používame preto, že je
akceptovateľný oboma systémami – 4.3BSD i Systém V.
SIGCONT
(4.3BSD) Ak má proces v
4.3BSSD, ktorý bol prerušený (viď. nasledujúce popisy signálov SIGSTOP
a SIGTSTP), pokračovať, odošle sa tento signál. Napr. keď došlo k
prerušeniu editora pri plnej obrazovke, môže byť pri pokračovaní
vykreslená znovu celá obrazovka.
SIGEMT
Tento signál je generovaný
implementáciou závislou na chybách hardwaru.
SIGEPE
Tento signál je generovaný
implementáciou závislou na podmienkach hardwaru. Napr. 4.3BSD na počítači
VAX používa tento signál k určeniu podmienok pohyblivej desatiny čiarky
(t.j. jeho podtečení) a podmienok celočíselnej aritmetiky (t.j. delenie
nulou).
SIGHUP
Ak je terminál uzavretý,
odošle sa signál odpojený ( hangup) každému procesu, pre ktorý je terminál
riadiaci. Tento signál je taktiež odoslaný všetkým procesom v danej
skupine procesov, keď skončí vedúci proces danej skupiny.
SIGILL
Tento signál je generovaný
implementáciou závislou na podmienkach hardwaru.
SIGINT
Tento signál prerušenie býva
generovaný, keď na terminále zadáte klávesu prerušenie.
SIGIO
(4.3BSD) Tento signál určuje,
že je V/V možné na deskriptoru súboru. 4.3BSD ju využíva, aby poskytol
procesu formu asynchronného V/V.
SIGLIOT
Tento signál sa generuje
implementáciou závislou na chybách hardwaru. Naviac verzia System V pri
príkazu abort odosiela tento signál aktuálnemu procesu. (Jedná sa o prípad,
keď proces odosiela signál sám sebe). Funkcia abort je volaná procesom,
aby vygenerovala obraz pamäte a ukončila proces, pokiaľ sa vyskytne
abnormálna chybová podmienka. Vo verzii 4.32 BSSD vysiela funkcia abort
sama sebe signál SIGILL, pre ukončenie s uložením obrazu pamäte.
SIGKILL Tento signál je jediným zaručeným spôsobom, ako ukončiť
proces, pretože príjímací proces nemôže tento signál ignorovať alebo
zachytiť.
SIGPIPE
Pokiaľ signál zapisuje do rúry
alebo FIFO a v danom okamihu neexistujú procesy, ktoré by z tejto rúry
alebo FIFO čítali, je signál odoslaný zapisujúcemu. Tento signál je rovno
generovaný systémom 4.3BSD, keď proces zapisuje do schránky, ktorá je
odpojená.
SIGPOLL
(Systém V) Na prúdovom
zariadení sa objavila istá udalosť. System V ponúka tento signál, aby
umožnil previesť asynchrónne V/V na jednom alebo viac prúdových zariadení.
SIGPROF
(4.3BSD) 4.3BSD má tri
mechanizmy pre alarm: SIGALARM, ktorý meria reálny čas procesu,
mechanizmus virtuálneho času (SIGVTALARM), ktorý meria „virtuálny
čas“ procesu (čas behu procesu) a mechanizmus (SIGPROF), ktorý
meria ako virtuálny čas tak čas behu jadra, ktorý bol využitý pre potreby
procesu. Signál SIGPROF je využívaný intepretery k profilovaniu priebehu
interpretovaného programu.
SIPGWR
(Systém V)
Tento signál upozorňuje na výpadok prúdu, ale jeho realizácia je závislá
na danej implementácii. Prevozné dokumentácie Systém V.
SIGQUIT
K generovaniu
tohto signálu dochádza v okamihu, keď na terminálu zadáte klávesu quit.
Daný signál je podobný ako signál SIGINT, ale SIGQUIT naviac
generuje obraz pamäti procesu.
SIGSEGV
Uvedený
signál je generovaný implementáciou závislou na hardwarovej chybe.
Porušenie segmentácie sa obvykle generuje vtedy, keď proces odkazuje na
oblasť pamäte, ku ktorej nemá povolený prístup.
SIGSTOP
(4.3BSD)
Tento signál zastavuje proces. Podobne ako signál SIGKILL, ani
signál SIGSTSOP nemôže byť ignorovaný alebo zachytení. Poskytuje
tak správcovi systému možnosť pozastavenia procesu. Proces zastavenia
signálom SIGSTOP môže pokračovať po zadaní signálu SIGCONT.
SIGSYS
Daný signál indikuje výskyt
neplatného volaného jadra. Z historických dôvod sa tento signál generuje
taký v prípade, že argument whence volaného jadra lseek nie je rovný 0, 1
alebo 2.
SIGTERM
Signál programového ukončenia.
Je to signál, ktorý je implicitne odoslaný procesu, ak je použitý príkaz
kill. (Pozor, nezameňte príkaz kill za volanie jadra tohto znenia.)
SIGTRAP
Tento signál sa používa s
volaním jadra ptrace a umožňuje procesu, aby bol spustený s trasovaním.
Býva používaný ladiacimi programami.
SIGTSTP
(4.3 BSD) Tento signál býva
odoslaná procesu v prípade, že bola na klávesnici zadná klávesa
pozastavenia (CTRL + Z) alebo klávesa pre opozdené prerušenie (CTRL + Y).
Proces, ktorý bol pozastavený môže pokračovať po signále SIGCONT.
SIGTTIN
(4.3BSD) Tento signál sa
generuje, keď sa proces na pozadí pokúša čítať zo svojho riadiaceho
terminálu. 4.3BSD generuje tento signál preto, že pri viacerých pokusoch o
čítaní z terminálového zariadenia môže dojsť ku zmiešaniu vstupov. Pokiaľ
proces tento signál ignoruje, je implicitne pozastavený.
SIGTTOU
(4.3BSD) Tento signál je
podobný SIGTTIN, ale k jeho generovaniu dochádza v prípade, že sa
proces na pozadí pokúša písať na svoj riadiaci terminál. Implicitne môže
proces na pozadí písať na svoj riadiaci terminál, ale je rovnako možné
určiť, aby sa miesto tohto zápisu vygeneroval signál SIGTTOU
SIGURG
(4.3BSD) Pri
vzniku nejakej naliehavej podmienky (napríklad dáta mimo rozsah) sa
generuje signál SIGURG. Tento signál využíva pseudoterminálový
ovládač.
SIGUSR1
Ku
komunikácii medzi procesmi sa využívajú i dva signály definované
užívateľom. Je nutné si všimnúť, že v prípade, kedy sa signál použije pre
komunikáciu medzi dvoma alebo viacerými procesmi, predá sa prijímajúcemu
procesu len informácia o typu signálu (nedá sa teda predať ID
odosielajúceho procesu). Signál neprenáša žiadnu inú informáciu než sám
seba. Z tohoto dôvodu sa signály používajú pre komunikáciu medzi procesmi
len zriedka.
SIGUSR2
viď SIGURS1.
SIGVTALRM
(4.3BSD) viď SIGPROF.
SIGWINCH
(4.3BSD) Zmenila sa veľkosť
terminálového okna.
SIGXCPU
(4.3BSD) Systém 4.3BSD
umožňuje limitovať zdroje pridelené procesu, čo ovplyvňuje proces i
procesy ním vytvorené. Tieto limity sú:
-
množstvo času CPU, ktorý
môže každý proces využiť
-
maximálna veľkosť jedného
vytvoreného súboru
-
maximálna veľkosť dátového
segmentu procesu
-
maximálna veľkosť zásobníka
procesu
-
maximálna veľkosť možného
vygenerovaného obrazu pamäti
-
maximálna veľkosť
rezidentnej časti procesu
SIGXFSZ
(4.3BSD) Tento signál určuje,
že proces prekročil limit veľkosti súboru
// Signály
koniec
Nahor
|
|
Index
Úvod
Rúry
Ako vytvoriť
rúru
Návratová
hodnota
Deskriptory
Príklad 1)
Príklad 2)
Príklad 3)
Signály
Základné vlastnosti
Spracovanie signálu
Poslanie signálu
Pozastavenie procesu
Jednoduchý príklad
Podmienky generovania
Čo ďalej so signálom
Spoľahlivé signály
Prehľad signálov
Tabuľka signálov
Iné
Infomácie
Ján Perháč
Peter Špireng
|
|