You are on page 1of 5

Exerccios P2 1) Considerando os comandos apresentados a seguir, faa o grafo de precedncia e escreva o programa concorrente com o uso de fork/join.

a = b + c ; (s0) d = e + f ; (s1) g = d + k ; (s2) h = g + a ; (s3) m = n + h ; (s4) x = m + h ; (s5) y = x + g ; (s6) z = y + 3; (s7) Na apostila tem exemplos (captulo 2). 2) Escreva, com a primitiva fork, tal como definida no sistema operacional Unix, um programa que represente um grafo com seis nodos. Na apostila tem exemplos (captulo 2). 3) Faa uma comparao entre processos pesados e processos leves. Processos pesados: so os processos tradicionais. Possuem uma thread inicial que comea a sua execuo, executam um cdigo seqencial e normalmente carregados do disco para execuo. Processos leves: so criados para permitir paralelismo na execuo de um processo pesado. As principais caractersticas dos processos leves so: Cada um roda um cdigo seqencial, pessuem sua prpria pilha de execuo e o seu prprio program counter, compartilham o uso do processor, podem criar processos (threads) filhos, compartilham o mesmo espao de endereamento. 4) Fale sobre as alternativas de implementao de threads a nvel de usurio, a nvel de sistema e sobre a soluo que combina estas duas alternativas. Estas alternativas esto descritas na apostila (captulo 2). 5) Analise o programa a seguir de maneira a verificar se esta correta a soluo para o problema da excluso mtua. Se no estiver, mostre o cenrio em que ocorrem as falhas da soluo. # Programa exclusao mutua int c1 = 1 ; int c2 = 1 ; void * p0 ( ) { for(;;) { c1 := 0 ; while (c2 == 0) {} "secao critica" c2 := 1 ; } } void * p1 ( ){ for(;;) { c2 := 0 ;

while (c1 == 0) {} "secao critica" c2 := 1 ; } } main () { thr_create ( p0) ) ; thr_create ( p1) ) ; thr_join() ; thr_join () ; } Problemas: a) os dois processos podem ficar eternamente bloqueados: - P0 faz c1 = 0 e perde oprocessador - P1 faz c2 = 0 - A seguir, os dois ficam bloqueados eternamente no while. b) Se P0 ganha o processador e executa a seo crtica, P1 ficar eternamente bloqueado no while, pois c1 ser eternamente 0. 6) Escreva um programa concorrente formado por duas threads, que executam um loop eterno de printfs, sendo que a impresso deve ocorrer sempre na seqncia t0, t1, t0, t1,... Use o algoritmo de Peterson para sincronizao. #include <pthread.h> pthread_t tid1,tid2; int vez = 0 ; int a, turn = 0 ; int flag[2] ; void * p0(){ int i ; printf("Thread P0\n"); for (i=0;i<1000000; i++) { flag[0] = 1 ; turn = 1 ; while((flag[1]==1) && (turn == 1)){} if (vez == 0) { printf (t0\n) ; vez = 1 ; } flag[0] = 0 ; }

void * p1(){

int i ; printf("Thread P1\n"); for (i=0;i<1000000; i++) { flag[1] = 1 ; turn = 0 ; while((flag[0]==1) && (turn == 0)){} if (vez == 1) { printf (t1\n) ; vez = 0 ; } flag[1] = 0 ; } } main(){ flag[0] = 0 ; flag[1] = 0 ; printf("THIS IS MAIN\n"); pthread_create(&tid1, NULL, p0, NULL); pthread_create(&tid2, NULL, p1, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); }

7) Considerando que dois processos, um produtor e um consumidor compartilham um buffer de um elemento, escreva um programa concorrente com o uso da soluo de Peterson para sincronizar as aes do produtor e do consumidor. #include <pthread.h> pthread_t tid1,tid2; int vez = 0 ; int buf ; int a, turn = 0 ; int flag[2] ; void * produtor(){ int i ; printf("Thread Produtor\n"); for (i=0;i<1000000; i++)

flag[0] = 1 ; turn = 1 ; while((flag[1]==1) && (turn == 1)){} if (vez == 0) { buf = i ; vez = 1 ; } flag[0] = 0 ; }

} void * consumidor(){ int i ; printf("Thread Consumidor\n"); for (i=0;i<1000000; i++) { flag[1] = 1 ; turn = 0 ; while((flag[0]==1) && (turn == 0)){} if (vez == 1) { printf (%d\n, buf) ; // consumir vez = 0 ; } flag[1] = 0 ; } } main(){ flag[0] = 0 ; flag[1] = 0 ; printf("THIS IS MAIN\n"); pthread_create(&tid1, NULL, produtor, NULL); pthread_create(&tid2, NULL, consumidor, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); }

8) Escreva um programa concorrente formado por dois processos (THREADS) que sincronizam suas aes com o uso da soluo de Peterson. Um dos processos conta at 500, e ento deve esperar pelo outro que conta at 1000, e vice-versa. Considere que a execuo comea pela THREAD que conta at 500. #include <pthread.h> pthread_t tid1,tid2; int vez = 0 ;

int turn = 0 ; int flag[2] ; void * t0(){ int i, k ; printf("Thread t0\n"); for (i=0;i<1000000; i++) { flag[0] = 1 ; turn = 1 ; while((flag[1]==1) && (turn == 1)){} if (vez == 0) { for (k=0; k<500; k++){}; // contar ate 500 vez = 1 ; } flag[0] = 0 ; } } void * t1(){ int I, k ; printf("Thread t1\n"); for (i=0;i<1000000; i++) { flag[1] = 1 ; turn = 0 ; while((flag[0]==1) && (turn == 0)){} if (vez == 1) { for (k=0; k<1000; k++){}; // contar ate 1000 vez = 0 ; } flag[1] = 0 ; } } main(){ flag[0] = 0 ; flag[1] = 0 ; printf("THIS IS MAIN\n"); pthread_create(&tid1, NULL, t0, NULL); pthread_create(&tid2, NULL, t1, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); }