Sunteți pe pagina 1din 11

Nemoianu Adile-Elena

Grupa: 4.2

Sisteme de operare
Tema 3

 Se consideră un program C ce conţine două procese (părinte + fiu).


 Procesul părinte va trimite, printr-un pipe, timp de 5s caracterul “a” către procesul
fiu, în plus la fiecare secundă o să trimită semnalul SIGUSR1.
 Procesul fiu va citi caracterele din pipe şi va realiza o statistică ce va conţine
numărul total de caractere, precum şi numărul de caractere primite după fiecare
semnal SIGUSR1.
 La final statistica va fi trimisă printr-un pipe procesului părinte ce o va afişa.

//biblioteci

#include<stdio.h>

#include<sys/types.h>

#include<sys/wait.h>

#include<sys/stat.h>

#include<dirent.h>

#include<string.h>

#include<unistd.h>

#include<signal.h>

#include<stdlib.h>

//Definim valorile universale

unsigned long numar_total = 0;

//numarul total de caractere „a” din statistica


Nemoianu Adile-Elena
Grupa: 4.2

unsigned long numar_curent = 0;

//numarul curent de caractere „a” citite

unsigned long sirul_de_caractere_a_[5];

// punem 5 pentru ca „a” se trimite timp de 5 secunde

unsigned long contor_sir = -1;

unsigned long numar_secunde = 0;

//contorul pentru secunde

/* Cand parintele scrie, fiul citeste, dar asta se intampla

numai dupa ce parintele a terminat de scris.

In cazul in care fiul scrie, atunci parintele citeste, dar

din nou, doar dupa ce fiul a terminat de scris. Deci,

comunicarea dintre cele doua procese se poate realiza doar

unidirectional si de aceea, vom folosi un pipe pentru

a conecta iesirea unui proces cu intrarea celuilalt proces,

in cazul nostru, cele doua procese fiind parintele si fiul.*/

//definim cele doua procese: parinte si fiu

pid_t fiu;

pid_t parinte;

//Definim cele doua pipe-uri:

//Parintele trimite caracterele catre fiu prin urmatorul pipe.


Nemoianu Adile-Elena
Grupa: 4.2

//(Fiul doar le va citi)

int pipe_trimitere_caractere[2];

//punem 2, deoarece avem doar 2 valori -- 0 sau 1--

//Fiul trimite statistica catre parinte prin urmatorul pipe.

//(Parintele doar o va citi.)

int pipe_trimitere_statistica[2];

//punem 2 deoarece avem doar doua valori -- 0 sau 1--

//Semnal_trimitere_a (SIGUSR1) va fi folosit timp de 5

//secunde pentru a transmite caracterul „a”

//Semnal_terminare_transmitere_a (SIGUSR2) este folosit

//dupa 5 secunde,o singura data pentru terminarea procesului

//fiu

/*Urmatoarea functie se va executa cand fiul primeste

semnalul Semnal_terminare_transmitere_a (SIGUSR1)*/

void Functie_terminare_citire_caractere_a(int semnal){

int i; //definim pasul

write(pipe_trimitere_statistica[1], & numar_total, sizeof(unsigned long));


Nemoianu Adile-Elena
Grupa: 4.2

//In pipe 2, se scrie de catre procesului fiu numarul

//total de caractere primite.

for (i = 0; i < 5; i++){

write(pipe_trimitere_statistica[1], & sirul_de_caractere_a_[i],


sizeof(unsigned long));

//In pipe 2 se scrie de catre procesului fiu cate

//caractere „a” se primesc pentru fiecare secunda.

close(pipe_trimitere_statistica[1]);

//Cand s-au incheiat cele 5 secunde si s-a terminat

//instructiunea „for”, inchidem procesul de scriere

exit(0);

void Creeaza_Statistica(int semnal){

printf("Proces fiu confirma: Am primit caracterul „a”!\n");

contor_sir++; //marim contorul

sirul_de_caractere_a_[contor_sir] = numar_curent;

//actualizam statistica

numar_total += numar_curent;

//calculam numarul total de caractere

numar_curent =0;
Nemoianu Adile-Elena
Grupa: 4.2

//se reseteaza numarul curent de caractere citite

/*Functia care se executa cand parintele primeste statistica

si o afiseaza*/

void functie_de_atentionare(int semnal){

int i = 0;

if (numar_secunde == 5){

//Daca au trecut cele 5 secunde in care parintele a

//transmis fiului caracterul „a”, urmeaza functiile:

kill(fiu, SIGUSR2);

//se transmite semnalul de_terminare_transmitere_a a

//procesului fiu

read(pipe_trimitere_statistica[0], &numar_total, sizeof(unsigned long));

//Se citeste statistica obtinuta de la fiu, cu ajutorul

//functiei „read”

printf("Fiul a terminat de calculat statistica!\n");

printf("Numar total de caractere trimis este: %ld\n", numar_total);

while (read(pipe_trimitere_statistica [0], & sirul_de_caractere_a_[i],


sizeof(unsigned long)) > 0)

// sirul_de_caractere_a_[i]= cate caractere se citesc la


Nemoianu Adile-Elena
Grupa: 4.2

//pasul i

printf("Numar de caractere „a” dupa fiecare semnal SIGUSR1 este


%d: %ld\n",i+1, sirul_de_caractere_a_[i]);

i++;

close(pipe_trimitere_statistica[0]);

//inchidem trimiterea statisticii

exit(0);

} else {

//Daca inca nu s-au terminat cele 5 secunde si parintele

//inca transmite caracterele „a” fiului sau, atunci:

kill(fiu, SIGUSR1);

//Se trimite semnalul Semnal_trimitere_a procesului fiu

numar_secunde ++;

//Se creste numarul de secunde...pana va ajunge la 5

alarm(1);

// In acest timp...se seteaza o noua alarma

int main(void){

char container;

int i;
Nemoianu Adile-Elena
Grupa: 4.2

//Testam erorile de transmitere a datelor

if (pipe(pipe_trimitere_caractere) < 0)

//Testam capacitatea de transmitere a caracterelor "a"

perror("Eroare de transmitere! Nu s-au inregistrat caractere!");

exit(1);

if (pipe(pipe_trimitere_statistica) < 0)

//Testam capacitatea de transmitere a statisticii

perror("Eroare de transmitere! Nu s-a putut realiza statistica! ");

exit(1);

if ((fiu = fork()) < 0)

//Testam legatura de transmisie intre parinte si fiu

perror("Eroare de transmisie intre parinte si fiu!\n");

exit(2);

//Prin apelul de sistem fork procesul fiu va mosteni toti

//descriptorii de fisiere pentru procesul parinte, creand

//astfel relatia parinte-fiu.


Nemoianu Adile-Elena
Grupa: 4.2

if (fiu == 0)

// Descriem activitatile procesului fiu, daca acesta exista

close(pipe_trimitere_caractere[1]);

//Inchide transmisia de caractere pentru primul pipe

close(pipe_trimitere_statistica[0]);

//Inchide citirea de caractere pentru statistica, pentru al doilea pipe

if (signal(SIGUSR1, Creeaza_Statistica) == SIG_ERR)

perror("Eroare in procesul fiu! Nu s-a creat statistica corect!\n");

exit(1);

if (signal(SIGUSR2, Functie_terminare_citire_caractere_a) == SIG_ERR)

perror("Eroare in procesul fiu! Nu s-au transmis caracterele


corect!\n");

exit(1);

while(read(pipe_trimitere_caractere [0], &container, 1) > 0)

//citeste din pipe_trimitere_caractere in container (spatiu de depozitare) cate un


caracter

numar_curent ++;
Nemoianu Adile-Elena
Grupa: 4.2

close(pipe_trimitere_caractere [0]);

//daca e [0] e capatul de citire, daca e [1] e capatul de

//scriere

close(pipe_trimitere_statistica [0]);

exit(0);

} else

//PROCESUL PARINTE

//Descriem activitatile procesului parinte

close(pipe_trimitere_caractere [0]);

//Inchide capatul de scriere (transmisia de caractere)

//pentru primul pipe

close(pipe_trimitere_statistica [1]);

//Inchide capatul de citire (citirea statisticii)

//pentru al doilea pipe

if (signal(SIGALRM, functie_de_atentionare) == SIG_ERR){

perror("Eroare in procesul parinte, la functia de atentionare de


primire a datelor de la fiu!\n");

exit(1);

alarm(1);
Nemoianu Adile-Elena
Grupa: 4.2

//se initializeaza prima alarma

while(1){

//procesul parinte scrie incontinuu in pipe

write(pipe_trimitere_caractere [1], "a", 1);

//Parintele va scrie caracterul „a” in pipe-ul 1, pana va

//intalni o noua alarma

close(pipe_trimitere_caractere[0]);

//Inchide capatul de scriere (transmisia de caractere)

//pentru primul pipe

close(pipe_trimitere_statistica[1]);

//Inchide capatul de citire (citirea statisticii) pentru

//al doilea pipe

return 0; //sfarsitul meniului principal

}
Nemoianu Adile-Elena
Grupa: 4.2

S-ar putea să vă placă și