lucrarea3b
DESCRIPTION
Despre linuxTRANSCRIPT
Lucrarea 3B
Lucrarea 3BConducte (PIPE) n Linux
Pipe-ul este un mecanism de comunicare intre procese. Dup cum i spune i numele, funcionarea sa este similara cu cea a unei conducte unidirecionale, avnd un capt prin care se scriu date i un capt de unde se citesc datele din conduct.O conduct se creeaz cu apelul :
#include
int pipe(int filedes[2]);
n caz de succes, pipe ntoarce 0 crendu-se o pereche de descriptori de fiier pentru cele dou capete ale conductei. filedes[0] este captul de citire i filedes[1] este captul de scriere.n caz de eroare, funcia ntoarce 1, errno fiind setat cu codul corespunztor erorii.Citirea din conduct se face cu apelul:
#include
ssize_t read(int fd, void *buff, size_t count);
n cazul citirii dintr-o conduct, primul parametru trebuie s fie un descriptor al unui capt de citire, nc deschis. Urmtorii parametri specifica adresa de memorie unde (buff) o sa fie memorai cei maxim count octei citii. Datele citite sunt nlturate din conduct, aceleai date neputnd fi citite de dou ori.Funcia ntoarce numarul de octei citii sau 1 n caz de eroare.Pentru scriere exist apelul:
#include
ssize_t write(int fd, void *buff, size_t count);
Parametrii sunt: descriptorul captului de scriere, adresa de memorie unde se afl datele care vor fi scrise i numrul de octei care vor fi scrii. Funcia ntoarce numrul de octei scrii sau 1 n caz de eroare.n cazul scrierii ntr-o conduct avem urmtoarele cazuri:
Dac se scriu mai puin de PIPE_BUF + 1 octei, sistemul de operare va efectua scrierea atomic, ateptnd pn cnd exist suficient spaiu dac este nevoie.
Dac n conduct exist suficient spaiu, specificat de PIPE_SIZE, pentru datele care urmeaz s fie scrise atunci acestea sunt scrise atomic. Altfel, datele sunt scrise pe msur ce apare spaiu liber n urma citirilor.
Dac se scriu mai mult de PIPE_BUF octei i n conduct nu exist suficient spaiu, datele sunt scrise n etape, pe msur ce apare spaiu liber. Dac mai multe procese se afl n aceast situaie atunci datele pot fi interclasate. Funcia se termin doar dup ce sunt scrise toate datele.
Dac se scrie ntr-o conduct al crui capt de citire a fost nchis atunci este generat semnalul SIGPIPE, citirea ntorcnd eroare, errno fiind setat cu EPIPE.
Comportamentul n cazul citirii dintr-o conduct este urmtorul:
Dac n conduct se afl cel puin count octei atunci se citesc exact count octei.
Dac n conduct se afl mai puin de count octei, atunci se citesc toate datele din conduct.
Dac conducta este vid i captul de scriere mai este deschis, atunci citirea este blocat pn sunt scrise date n conduct.
Dac conducta este vid i captul de scriere este nchis atunci citirea ntoarce 0.
n urmtorul exemplu, procesul printe creeaz un copil care "tie" s determine numerele lui Fibonacci i s adune 2 numere. Comunicaia se face, firete, cu ajutorul unor conducte. Se creeaz dou conducte deoarece comunicaia se desfoar n ambele sensuri. Pentru a-i cere s determine un anumit numr fibonacci, printele trimite mesajul "fibonacci" urmat de un mesaj cu indexul dorit dup care ateapt s citeasc un ntreg. Pentru a-i cere s fac o adunare, se trimite comanda "add", urmat de dou mesaje cu cele 2 numere, dup care citete rspunsul. Copilul asteapt un mesaj de la printe coninnd comanda care trebuie executat. n funcie de comand va tii cte valori ntregi mai trebuie s citeasc.
#include #include #include #include
#define COMMAND_SIZE 20
char fib[] = "fibonacci";char add[] = "add";char end[] = "end";
int fibonacci(int n) {if (n < 2) {return n;}return fibonacci(n -1) + fibonacci(n - 2);}
void childProc(int readPipe, int writePipe) {char message[20];int a, b;do {read(readPipe, message, COMMAND_SIZE);printf("primit %s\n", message);if (strcmp(message, add) == 0) {read(readPipe, &a, sizeof(a));read(readPipe, &b, sizeof(b));a += b;write(writePipe, &a, sizeof(a));
} else if (strcmp(message, fib) == 0){read(readPipe, &a, sizeof(int));b = fibonacci(a);write(writePipe, &b, sizeof(int)); }
} while (strcmp(message, end));printf("the wonder child has finished!\n");exit(1);}
void parentProc(int readPipe, int writePipe) {int a, b, rez;write(writePipe, fib, COMMAND_SIZE);a = 3;write(writePipe, &a, sizeof(int));read(readPipe, &rez, sizeof(int));printf("%s(%d) = %d\n", fib, a, rez);a = 2;b = 5;write(writePipe, add, COMMAND_SIZE);write(writePipe, &a, sizeof(int));write(writePipe, &b, sizeof(int));read(readPipe, &rez, sizeof(int));printf("%d + %d = %d\n", a, b, rez);
write(writePipe, end, strlen(end) + 1);}
int main() {
int firstPipe[2];int secondPipe[2];int pid;
if (pipe(firstPipe)) {printf("Nu am putut crea conducta!\n");exit(-1);}if (pipe(secondPipe)) {printf("Nu am putut crea conducta!\n");exit(-1);}
pid = fork();
if (pid) {if (pid == -1) {printf("Nu am reusit crearea procesului copil.\n");exit(-1);}
parentProc(secondPipe[0], firstPipe[1]);
} else {childProc(firstPipe[0], secondPipe[1]);}wait(NULL);printf("Procesul principal gata!\n");}
Probleme propuse.
S se adune elementele unui vector folosind N procesoare. Folositi numai procese.
S se determine ct mai rapid dac o valoare se gsete ntr-un vector, folosind procese care ruleaz pe un calculator cu N procesoare.
S se determine ct mai rapid pe ce poziii se gsete ntr-un vector o valoare dat, folosind procese care ruleaz pe un calculator cu N procesoare.