7. týždeň

Medziprocesová komunikácia - Signály

Ciele

  1. Oboznámiť sa s pojmom signál
  2. Naučiť sa pracovať so signálmi

Postup

Krok 1: Signál

Príprava

Pre prácu na cvičení si stiahnite súbor k cvičeniu.

Obsah súboru:

.
└── 07
    ├──u1_1.c
    ├──u2_1.c
    ├──Makefile
    └──tests
       └──u1_1_test.sh

Poznámka

Programy je možné kompilovať pomocou make nazov_suboru.c Napríklad: make u1_1.c

Úvod

Signál je komunikačný prostriedok. Je generovaný UNIXom/Linuxom ako odpoveď na výskyt konkrétnej udalosti. Keď je signál prijatý, tak naň môže proces reagovať.

Signály sú generované: operačným systémom, používateľským procesom.

Môžu byť: generované, odchytávané, * ignorované.

Názvy signálov sú definované v hlavičkovom súbore signal.h.

Štandardné signály v UNIX/Linuxe:

Názov č. Akcia Popis
SIGINT 2 Term prerušenie terminálu (ekvivalent k Ctrl + C z klávesnice)
SIGQUIT 3 Core ukončenie z klávesnice
SIGKILL 9 Term ukončenie procesu
SIGALRM 14 Term signál časovača pre službu alarm()
SIGTERM 15 Term terminačný signál
SIGCHLD 17 Ign proces potomka bol ukončený alebo prerušený
SIGSTOP 19 Stop zastaví proces
SIGWINCH 28 Ign signál zmeny veľkosti okna

Úloha 1.1

Signálov je omnoho viac. To aké ešte existujú si naštudujte v manuáli: man 7 signal

Ako sa volá kategória, pre ktorú je preddefinovaným správaním ignorovať signál?

Správna odpoveď: Ign
Nesprávna odpoveď

Ako sa volá kategória, pre ktorú je preddefinovaným správaním ukončiť proces?

Správna odpoveď: Term
Nesprávna odpoveď

Uveďte názov signálu generovaného pri výskyte chyby výpočtu v pohyblivej rádovej čiarke:

Správna odpoveď: SIGFPE
Nesprávna odpoveď

Krok 2: Práca so signálmi

Príkaz shellu kill

Pomocou príkazu kill je signál okamžite zaslaný buď jednému procesu alebo skupine procesov. Ako parameter prijíma voliteľné číslo signálu a PID procesu. Ak nie je zadané žiadne číslo signálu, tak sa odošle signál SIGTERM.

kill [-signal|-s signal|-p] [-q value] [-a] [--] pid|name...

Poznámka

Podrobnejšie informácie k príkazu kill sa nachádzajú v manuáli: man kill

Koľko parametrov má príkaz kill?

Správna odpoveď: 2
Nesprávna odpoveď

Príklady použitia kill:

Odoslanie signálu SIGTERM procesu s PID = 15

kill 15

Odoslanie signálu SIGTERM procesom patriacím do skupiny s PGID = 15

kill -15

Odoslanie signálu SIGTERM všetkým procesom okrem procesu s PID = 1 Proces s PID = 1 je init proces. Jedná sa o proces, ktorý riadi spúšťanie iných procesov.

kill -1

Odoslanie signálu SIGKILL viacerým procesom (32, 55, 78)

kill -9 32, 55, 78

Služba jadra signal()

Slúži na odchytenie príchodu špecifického signálu.

#include <signal.h>

typedef void(*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

Parametere
int signum typ signálu (napr. SIGINT)
sighandler_thandler obslužná funkcia - reakcia, čo sa stane, keď bude procesu poslaný signál
Návratová hodnota
Pri úspešnom vykonaní vráti prechadzajúcu hodnotu signálu.
Pri chybe SIG_ERR.

Príklad použitia:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void obsluzna_funkcia(int sig){
    printf("\nSignal %d bol prave odchyteny.\n", sig);
    printf("Nastavujem povodnu reakciu na signal SIGINT.\n");
    signal(SIGINT, SIG_DFL);
}

int main(){
    printf("Program bude v sekundovych intervaloch vypisovat retazec 'Hello World!'.\n");
    signal(SIGINT,obsluzna_funkcia);

    while(1){   
        printf("Hello world!\n");
        sleep(1);
    }
    return(0);
}
Opis kódu:

Program pozostáva z hlavnej funkcie main a obslúžnej funkcie s príslušným názvom. V hlavnej funkcií je zmenená reakcia na prijatie signálu SIGINT z klasickej na funkciu obsluzna_funkcia. Po zachytení signálu SIGINT, ktorý reprezentuje stlačenie kombinácie kláves CTRL + C sa táto obslúžna funkcia zavolá. V nej sa zmení reakcia na signál SIGINT na tú prednastavenú (SIG_DFL). Program je možné ukončiť opätovným stlačením kláves CTRL + C.

Upozornenie

V prípade, že by sa v obslúžnej funkcií nenastavila pôvodná reakcia na signál SIGINT, by nebolo možné ukončiť program prostredníctvom kombinácie kláves CTRL + C.

Výstup z programu:

Program bude v sekundovych intervaloch vypisovat retazec 'Hello World!'.
Hello world!
Hello world!
^C
Signal 2 bol prave odchyteny.
Nastavujem povodnu reakciu na signal SIGINT.
Hello world!
Hello world!
Hello world!
^C

Akú číselnú hodnotu má signál SIGKILL?

Odoslať odpoveď
Správna odpoveď: 9
Nesprávna odpoveď

Služba jadra kill()

Slúži na zaslanie signálu procesu alebo skupine procesov.

#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int sig);
Parametere
pid_t pid ak je hodnota pid kladná, tak je signál odoslaný procesu s ID špecifikovaným pomocou pid
ak je hodnota pid 0, tak je signál poslaný každému procesu v skupine procesov, v ktorej sa nachádza volajúci proces
ak je hodnota pid -1, tak je signál poslaný každému procesu, pre ktorý má volajúci proces právo posielať signály, okrem procesu 1 (init)
ak je hodnota pid menšia ako -1, tak je signál poslaný každému procesu v skupine procesov, ktorej ID je -pid
int sig ak je hodnota sig 0, tak nie je poslaný žiaden signál ale overenie existencie a práv prebehne
Návratová hodnota
Pri úspešnom vykonaní vráti 0.
Pri chybe -1.

Príklad použitia:

#define _POSIX_SOURCE //Musí byť definované na začiatku pred include kvôli kompilácií.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>

//Obslužná funkcia
void obsluzna_funkcia(int sig){
    printf("Signal %d bol odchyteny.\n",sig);
}

int main(){
    printf("Spustenie hlavneho programu.\n");
    pid_t pid = fork();
    switch(pid){
        case 0: 
            sleep(3);
            kill(getppid(), SIGABRT);
            exit(0);
        case -1:
            perror("Nastala chyba.");
            exit(1);
        default:    
            printf("Cakanie na prijatie signalu SIGABRT.\n");
            signal(SIGABRT, obsluzna_funkcia);//Zaregistruje obslužnú funkciu
            pause();//Tu čaká na signál
            printf("Koniec hlavneho programu.\n");
            exit(0);
    }
}
Opis kódu:

Najprv je spustený hlavný program. Následne sa vytvorí proces potomka prostredníctvom služby fork(). Proces rodiča (vetva default) využíva službu signal() na zachytenie signálu SIGABRT na ktorý bude reagovať prostredníctvom obslúžnej funkcie. Následne prostredníctvom služby pause() pozastaví svoje vykonávanie až do príchodu nejakého signálu. Proces potomka pošle po 3 sekundách signál SIGABRT procesu rodiča a ukončí sa. Následne sa ukončí aj proces rodiča.

Výstup programu:

Spustenie hlavneho programu.
Cakanie na prijatie signalu SIGABRT.
Signal 6 bol odchyteny.
Koniec hlavneho programu.

Aký návratový typ má služba signal()?

Správna odpoveď: ODPOVED1
Nesprávna odpoveď

Úloha 2.1

Vytvorte program, ktorý v hlavnom programe (funkcia main()) odošle aktuálnemu procesu signál SIGQUIT. Na tento signál nastavte obslužnú funkciu obsluzna_funkcia(), ktorá dokáže tento signál odchytiť a nastaví mu pôvodnu reakciu.

Poznámka

Zdrojové súbory k úlohe sa nachádzajú v priečinku 07 pod názvom u1_1.c. Pred testovaním je potrebné skompilovať program u1_1.c. Úlohu je možné testovať zadaním následovného príkazu do terminálu: ./tests/u1-1-test.sh

Služba jadra alarm()

Zaistí, že volajúcemu procesu sa po počte sekúnd, určenom v parametre služby, odošle signál SIGALRM.

#include <unistd.h>

unsigned int alarm(unsigned int seconds);
Parametere
unsigned int seconds počet sekúnd, po ktorom bude zaslaný signál SIGALRM
Návratová hodnota
Počet sekúnd zostavajúcich do uplynutia predchádzajúceho alarmu (ak nejaký naplánovaný bol).
0 ak pred tým nebol naplánovaný žiaden alarm().

Poznámka

Podrobnejšie informácie k službe alarm() sa nachádzajú v manuáli: man alarm

Príklad použitia:

#define _POSIX_SOURCE //Musí byť definované na začiatku pred include

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

//Obslužná funkcia
void obsluzna_funkcia(int sig){
    printf("Signal %d bol odchyteny.\n",sig);
}

int main(){
    signal(SIGALRM,obsluzna_funkcia);
    printf("Spustenie programu.\n");
    alarm(3);
    pause();
    printf("Koniec hlavneho programu.\n");
    return(0);
}
Opis kódu:

Program najprv nastaví prostredníctvom služby signal() odchytenie signalu SIGALRM, ktorý pochádza zo služby alarm(). Následne zavolá službu alarm() pomocou ktorej odošle signál SIGALRM volajúcemu procesu po 3 sekundách.

Môže niekedy služba alarm() skončiť chybou?

Správna odpoveď: Nie. Návratová hodnota služby alarm() je vždy hodnota 0 alebo celé kladné číslo, ktoré určuje počet sekúnd zostavajúcich do uplynutia predchádzajúceho alarmu (ak nejaký naplánovaný bol).
Nesprávna odpoveď

Služba jadra sigsuspend()

Služba jadra sigsuspend() pozastaví činnosť programu dovtedy, pokiaľ nie je programu poslaný nejaký signál.

#include <signal.h>

int sigsuspend(const sigset_t *mask);
Parametere
const sigset_t *mask dočasná maska, ktorá nahrádza tú pôvodnu. Ak sa ponechá prázdna (v príklade nižšie) tak proces čaká na akýkoľvek signál
Návratová hodnota
Stále -1.

Poznámka

Podrobnejšie informácie k službe sigsuspend() sa nachádzajú v manuáli: man sigsuspend

Príklad použitia:

#define _POSIX_SOURCE //Musí byť definované na začiatku pred include

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

//Obslužná funkcia
void obsluzna_funkcia(int sig){
    printf("Signal %d bol odchyteny.\n",sig);
}

int main(){
    printf("Spustenie hlavneho programu.\n");
    sigset_t mask;
    alarm(3);
    printf("Program caka na signal.\n");
    signal(SIGALRM, obsluzna_funkcia);
    sigsuspend(&mask);
    printf("Koniec hlavneho programu.\n");
    return(0);
}
Opis kódu:

V hlavnom programe sa vytvorí prázdna maska. Následne sa zavolá služba alarm() s parametrom 3 čo znamená, že sa po 3 sekundách odošle signál SIGALRM. Tak je prostredníctvom služby signal() nastavená reakcia na signál SIGALRM. Pomocou služby sigsuspend() sa pozastaví činnosť programu a pri použití prázdnej masky proces čaká na akýkoľvek signál.

V spojení s akou službou sa sigsuspend() bežne využíva? (Uveďte v tvare: služba()).

Správna odpoveď: sigprocmask()
Nesprávna odpoveď

Služba jadra sigaction()

Prostredníctvom služby sigaction() je možné zmeniť akciu vykonanú procesu po prijatí špecifického signálu.

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Parametere
int signum špecifikuje signál
const struct sigaction *act ak nie je NULL, tak špecifikuje novú akciu pre signál signum
const stuct sigaction *oldact ak nie je NULL, tak sa sem vloží predchadzajúca akcia signálu signum

Opis štruktúry sigaction:

struct sigaction{
    void (*sa_handler) (int);
    void (*sa_sigaction) (int, siginfo_t *,void*);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer) (void);
}
  • void (*sa_handler) (int) - obslužná funkcia - má rovnaký význam ako pri službe signal(),
  • void (sa_sigaction) (int, siginfo_t ,void*) - môžu byť použité príznaky SIG_IGN a SIG_DFL,
  • sigset_t sa_mask - špecifikuje masku signálov, ktoré by mali byť blokované počas vykonávania obslužnej funkcie. Blokované - t. j. pridané do signálovej masky vlákna, v ktorom je obslužná funkcia vyvolaná. Okrem toho bude signál, ktorý spustil obslužnú funkciu, zablokovaný, pokiaľ nie je použitý príznak SA_NODEFER.
  • int sa_flags - modifikuje správanie sa obslužnej funkcie signálu. Môže nadobúdať hodnoty:
    • SA_NOCLDSTOP - negeneruje sa signál SIGCHILD, keď sa potomkovia ukončia,
    • SA_RESETHAND - nastavuje pôvodnu akciu na daný signál (význam ako SIG_DFL),
    • SA_RESTART - reštartuje služby, ktoré môžu byť prerušené príchodom nejakého signálu,
    • SA_NODEFER - keď beží obslúžna funkcia a proces zachytí nejaký signál, tento signál sa nepridá do sady signálov.
Návratová hodnota
V prípade úspešného vykonávania je to 0.
V prípade chyby je to -1.

Poznámka

Podrobnejšie informácie k službe sigaction() sa nachádzajú v manuáli: man sigaction

Ktoré signály nie je možné blokovať tým, že sú špecifikované v _sa_mask_?

Odoslať odpoveď
Správna odpoveď: SIGKILL, SIGSTOP
Nesprávna odpoveď

Upozornenie

Príklad použitia bude uvedený po vysvetlení služieb sigemptyset(), sigaddset(), sigdellset() a sigprocmask().

Služby jadra sigemptyset(), sigfillset(), sigaddset(), sigdelset(), sigprocmask()

Služby sigemptyset() a sigfillset() majú byť volané vždy pred ostatnými službami. Argumentom týchto služieb je sada signálov, ktorej dátový typ je sigset_t.

sigemptyset()

Inicializuje sadu signálov.

sigfillset()

Naplní sadu signálov všetkými možnými signálmi.

sigaddset()

Pridá do sady konkrétny signál.

sigdelset()

Odstráni jeden alebo niekoľko signálov zo sady. Obvykle sa využíva po službe sigfillset().

Služba jadra sigprocmask()

Slúži na zablokovanie prijatia niektorého signálu pokiaľ nie je vykonávanie obslúžnej funkcie ukončené. Vďaka tomu je možné ochraniť časti programu, ktoré nesmú byť prerušené (napríklad príchodom nejakého signálu). Táto služba modifikuje aktuálnu signálovú masku.

#include <signal.h>

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
Parametere
int how určuje, ako má byť modifikovaná aktuálna signálová maska
const sigset_t *set ak je NULL, tak zostane signálová maska nezmenená ale aktuálna hodnota masky je napriek tomu vrátená v oldset (ak nie je NULL)
sigset_t *oldset ak nie je NULL, tak predchádzajúca hodnota signálovej masky je uložená v oldset

Parameter int how môže nadobúdať hodnoty: SIG_BLOCK - signály v dodanej sade sú pridané k blokovaným signálom aktuálnej sady SIG_UNBLOCK - signály v dodanej sade sú odstránené zo sady blokovaných signálov * SIT_SETMASK - kompletne nahrádza signálovú masku. Špecifikovaná sada nahradí aktuálnu sadu, v ktorej sa nachádzajú blokované signály

Návratová hodnota
V prípade úspešného vykonávania je to 0.
V prípade chyby je to -1.

Poznámka

Podrobnejšie informácie k službe sigprocmask() sa nachádzajú v manuáli: man sigprocmask

Príklad použitia k službám sigaction() a sigemptyset():

#define _POSIX_SOURCE
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

void obsluzna_funkcia(int sig){
    printf("Signal %d bol odchyteny.\n", sig);
}

int main(){
    struct sigaction act;
    act.sa_handler = obsluzna_funkcia;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGINT, &act, 0);
    int i=0;
    while(i<5){
        printf("Hello World!\n");
        sleep(1);
        i++;
    }
    printf("Koniec programu.\n");
}
Opis kódu:

Na začiatku je definovaná obslužná funkcia obsluzna_funkcia(). Následne je deklarovaná štruktúra sigaction. Tejto štruktúre je nastavená obslužná funkcia pomocou act.sa_handler = obsluzna_funkcia;. sigemptyset(&act.sa_mask); vyprázdni sadu signálov. Príznak štruktúry je inicializovaný na hodnotu 0 pomocou act.sa_flags = 0;, pretože nie je potrebné nastaviť špeciálne správanie sa obslužnej funkcie. Pomocou služby sigaction(), kde je na mieste prvého argumentu predaný SIGINT, sa nastaví odchytávanie signálu prerušenia. V závere sa v slučke vypisuje reťazec "Hello world!" v sekundových intervaloch. Po 5 sekundách sa ukončí činnosť programu.

Vysvetlenie funkcionality programu:

Program aj napriek stláčaniu klávesovej skratky CTRL + C bude vypisovať reťazec "Hello World!", pretože je v programe nastavené odchytávanie tohto signálu (SIGINT). Ukončiť program je možné pomocou klávesovej skratky CTRL + \, prípadne sa procesu tohto programu pošle signál kill -9.

Výstup z programu môže vyzerať nasledovne:

Hello World!
^CSignal 2 bol odchyteny.
Hello World!
Hello World!
Hello World!
Hello World!
Koniec programu.

Príklady použitia ďalších služieb:

Blokovanie všetkých signálov okrem SIGUSR1 a SIGUSR2

Nasledujúci príklad zablokuje všetky signály okrem SIGUSR1 a SIGUSR2: * Deklarácia sady signálov s názvom sig_set:

sigset_t sig_set;
  • Naplnenie sady všetkými možnými signálmi:
sigfillset(&sig_set);
  • Odstránenie signálov SIGUSR1 a SIGUSR2 zo sady:

Ako by ste odstránili signál SIGUSR1 zo sady sig_set? (Uveďte v tvare: služba(parameter);)

Správna odpoveď: sigdelset(&sig_set, SIGUSR1);
Nesprávna odpoveď

Ako by ste odstránili signál SIGUSR2 zo sady sig_set? (Uveďte v tvare: služba(parameter);)

Správna odpoveď: sigdelset(&sig_set, SIGUSR2);
Nesprávna odpoveď
  • Zaevidovanie upravenej masky:
sigprocmask(SIG_SETMASK, &sig_set,NULL);

Odblokovanie/odstránenie SIGINT, SIGQUIT:

  • Deklarácia:
sigset_t onesig, old_mask;
  • Inicializácia sady
sigemptyset(&onesig);
  • Pridanie signálov do sady:
sigaddset(&onesig, SIGINT);
sigaddset(&onesig, SIGQUIT);

Úloha 2.2

Doplňte do nasledujúci kód tak, aby signály v dodanej sade boli odstránené zo sady blokovaných signálov a aby sa následne uchovala stará sada v old_mask:

sigprocmask( [1. ............] , [2. ............] , [3. ............] );

1. parameter (Odpoveď uveďte bez medzier).

Správna odpoveď: SIG_UNBLOCK
Nesprávna odpoveď

2. parameter (Odpoveď uveďte bez medzier).

Správna odpoveď: &onesig
Nesprávna odpoveď

3. parameter (Odpoveď uveďte bez medzier).

Správna odpoveď: &old_mask
Nesprávna odpoveď

Príklad práce so signálmi:

Nasledujúci program najprv povolí signál SIGUSR1 a nastaví obslužnú funkciu. Následne tento signál zablokuje (nedôjde k zavolaniu obslúžnej funkcie).

#define _POSIX_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void obsluzna_funkcia(int sig){
    printf("Signal %d bol odchyteny.\n", sig);
}

int main(){
    printf("Spustenie hlavneho programu.\n");
    struct sigaction sigact;
    sigset_t sigset;

    //Prva cast
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigact.sa_handler = obsluzna_funkcia;
    sigaction(SIGUSR1, &sigact, NULL);
    printf("Prve poslanie signalu.\n");
    kill(getpid(), SIGUSR1);

    //Druha cast
    sigemptyset(&sigset);
    sigaddset( &sigset, SIGUSR1);

    sigprocmask(SIG_SETMASK, &sigset, NULL);
    printf("Druhe poslanie signalu.\n");
    kill(getpid(), SIGUSR1);
    printf("Ukoncenie programu.\n");
    return (0);
}
Opis kódu:

Najprv je zadeklarovaná štruktúra sigaction a sada signálov sigset. V prvej časti je nastavená štruktúra sigaction na obsluhu signálu SIGUSR1. Štruktúre sigaction je nastavená obslúžna funkcia obsluzna_funkcia(). Pri zaslaní signálu SIGUSR1 je na štandardný výstup vypísaný text: " Signal 10 bol odchyteny.". V druhej časti je najskôr vyčistená štruktúra sigaction a je do nej pridaný len signál SIGUSR1. Na danú sadu je nastavený signál a následne vykoná opätovné poslanie signálu.

Výstup z programu:

pred prvym poslanim signalu
som v obsluznej funkcii
pred druhym poslanim signalu
po druhom poslani signalu

Z výstupu je jasné, že program sa v prvej časti dostal aj do obslúžnej funkcie catcher. V druhej časti je už zablokované prijatie signálu SIGUSR1 a tak sa do obslúžnej funkcie program nedostane.

Aplikovanie poznatkov

Úloha 2.3

V nasledujúcom programe je vynechaných niekoľko časti. Dopĺňte čo tam patrí:

#define _POSIX_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void obsluzna_funkcia(int sig){
    printf("Signal %d bol odchyteny.\n", sig);
}

int main() {
    struct sigaction sigact;
    sigset_t sigset;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    [1.____________] = obsluzna_funkcia;
    sigaction(SIGUSR1, &sigact, NULL);  

    sigfillset(&sigset);
    sigaddset(&sigset, SIGUSR1);
    sigprocmask([2.____________], &sigset, NULL);

    printf("Prve poslanie signalu.\n");
    [3.____________](getpid(), SIGUSR1);

    printf("Pred odblokovanim signalu SIGUSR1.\n");
    [4.____________](&sigset, SIGUSR1);
    sigprocmask(SIG_SETMASK, &sigset, NULL);
    printf("Po odblokovani signalu SIGUSR1.\n");
    return (0);
}
  1. formulár:

    Ako nastavíte obslúžnu funkciu catcher? Odpoveď uveďte bez medzier.

    Správna odpoveď: sigact.sa_handler
    Nesprávna odpoveď
  2. formulár:

    Ako kompletne nahradite signálovú masku? Odpoveď uveďte bez medzier.

    Správna odpoveď: SIG_SETMASK
    Nesprávna odpoveď
  3. formulár:

    Na zaslanie signálu slúži služba: Odpoveď uveďte bez medzier a zátvoriek.

    Správna odpoveď: kill
    Nesprávna odpoveď
  4. formulár

    Pomocou akej služby odstránite signál zo sady? Odpoveď uveďte bez medzier a zátvoriek.

    Správna odpoveď: sigdelset
    Nesprávna odpoveď

Úloha 2.4

Predchadzajúci kód, do ktorého ste doplňali správne odpovede sa nachádza v priečinku 07 pod názvom u2_1.c. Pred testovaním je potrebné skompilovať program u2_1.c.

Poznámka

V archíve, ktorý ste si stiahli k cvičeniu máte predchadzajúci kód v súbore u2_1.c. Správne odpovede len doplňte namiesto [______].

V prípade úspešného doplnenia bude výstup z programu vyzerať nasledovne:

Prve poslanie signalu.
Pred odblokovanim signalu SIGUSR1.
Signal 10 bol odchyteny.
Po odblokovani signalu SIGUSR1.