lucrarea3B

download lucrarea3B

If you can't read please download the document

description

Despre linux

Transcript of lucrarea3B

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.