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