Buscar

04 Primitivas de sincronização

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 18 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 18 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 18 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Programação Paralela e Distribuída
04 - Primitivas de sincronização
Prof. Laerte M. Rodrigues
laerte.rodrigues@ifmg.edu.br
Primitivas de sincronização
I Muitas vezes em programas paralelos devemos controlar o
acesso à seção critítica evitando condições de corrida
I Controle de recursos também é crucial
I Não precisamos implementar estes algoritmos pois os mesmo já
existem
I Semáforos e monitores são os recursos para programação
concorrente para o controle deste tipo de situação
Semáforos
I Estratégia proposta por Dijkstra para resolver problemas de
busy-wait
I O semáforo têm 2 campos
I value: Um valor de controle do semáforo
I queue: Fila de threads que irão ter acesso ao semáforo
I Quando value for 0, a thread que requisitar o recurso ficará
bloqueada até outra liberá-la
I Este processo é feito por 2 rotinas
I P: Requisita o recurso, quando este não está disponível bloqueia o
processo
Semáforos
I V: Libera o recurso quando este não é mais necessário
I Semáforos binários (Com apenas 1 recurso) podem ser
utilizados para controle de seção crítica
I Também é conhecido como mutex
I Na Pthreads os semaforos estão implementados na biblioteca
semaphore.h
I sem_t: É a estrutura de dados que faz o controle do semáforo
I int sem_init(sem_t *sem, int pshared, unsigned int
value): Inicializa a estrutura
I sem_t *sem: Ponteiro para a estrutura do semáforo
I int pshared: Sempre será 0 (Flag indicando se o semáforo será
compartilhado entre processos)
Semáforos
I unsigned int value: Valor inicial do semáforo
I Retorna 0 se a inicialização do semáforo for feita corretamente
I int sem_wait(sem_t *sem): Implementação da rotina P
I int sem_post(sem_t *sem): Implementação da rotina V
I int sem_getvalue(sem_t *sem, int *valp): Retorna o
valor atual do semáforo
I sem_t *sem: Semáforo que será consultado
I int *valp: Variável que será utilizada para receber o valor do
semáforo
Produtor-consumidor
Produtor-consumidor
I Neste problema temos um buffer circular que é
compartilhado por 2 atores, o produtor e o consumidor
I O produtor alimenta o buffer, sendo que este deve ser bloqueado
se o buffer estiver cheio
I O consumidor esvazia o buffer e o mesmo deve ser bloqueado se
o buffer estiver vazio
I O buffer deve ser circular pois os elementos têm comportamento
de uma fila
Produtor-consumidor
Produtor-consumidor
I1 #include <iostream >
2 #include <pthread.h>
3 #include <semaphore.h>
4 #include <unistd.h>
5 #include <ctime >
6 #include <cstdlib >
7
8 using namespace std;
9
10 #define BUFFER_SIZE 10
11
12 int buffer[BUFFER_SIZE ];
13 int in = 0; // Indice de entrada do buffer
14 int out = 0; // Indice de saida do buffer
15
16 sem_t mutex; // Controle da secao critica
17 sem_t full; // Controle do buffer cheio
18 sem_t empty; // Controle do buffer vazio
Produtor-consumidor
19
20 void *produtor(void *p) {
21 while (1) {
22 int r = rand() % 100;
23
24 sem_wait (&full); // Espera se o buffer estiver cheio
25
26 // Secao critica
27 sem_wait (&mutex );
28 buffer[in] = r;
29 in = (in+1)% BUFFER_SIZE;
30 cout << "Produtor depositou " << r << endl;
31 sem_post (&mutex );
32 // Fim da secao critica
33
34 sem_post (&empty ); // Sinaliza que buffer pode nao estar mais vazio
35 usleep(rand ()%1000);
36 }
Produtor-consumidor
37 }
38
39 void *consumidor(void *p) {
40 while (1) {
41 sem_wait (&empty ); // Espera se o buffer estiver vazio
42
43 // Secao critica
44 sem_wait (&mutex );
45 cout << "Cosumidor pegou " << buffer[out] << endl;
46 out = (out +1)% BUFFER_SIZE;
47 sem_post (&mutex );
48 // Fim da secao critica
49
50
51 sem_post (&full); // Sinaliza possivel buffer
52 usleep(rand ()%1000);
53 }
54 }
Produtor-consumidor
55
56 int main() {
57 pthread_t threads [5];
58
59 srand(time(NULL ));
60
61 sem_init (&mutex ,0 ,1);
62 sem_init (&full ,0, BUFFER_SIZE );
63 sem_init (&empty ,0 ,0);
64
65 pthread_create (& threads [0],NULL ,produtor ,NULL);
66 pthread_create (& threads [1],NULL ,produtor ,NULL);
67 pthread_create (& threads [2],NULL ,consumidor ,NULL);
68 pthread_create (& threads [3],NULL ,consumidor ,NULL);
69 pthread_create (& threads [4],NULL ,consumidor ,NULL);
70
71 for(int i=0;i<2;i++) {
72 pthread_join(threads[i],NULL);
Produtor-consumidor
73 }
74
75 return 0;
76 }
Problema do leitor-escritor
I Controle de recursos em banco de dados compartilhados
I Evitar o problema de ghost-read
I Protocolo:
I 2 ou mais leitores podem acessar a base concorrentemente
I Sem conflito read-write: Um leitor e um escritor não podem
acessar concorrentemente
I Sem conflito write-write: 2 escritores não podem acessar a base
concorrentemente
I A idéia básica deste controle é
I Quando existir um leitor, outro também pode acessar a base
Problema do leitor-escritor
I O escritor só pode acessar a base quando não existe nenhum
leitor ou escritor
I Na implementação, wlock é o semáforo binário que bloqueia
leitores e escritores para o acesso
I1 #include <iostream >
2 #include <pthread.h>
3 #include <semaphore.h>
4 #include <unistd.h>
5 #include <ctime >
6 #include <cstdlib >
7 #include <ctime >
8
9 using namespace std;
10
Problema do leitor-escritor
11 sem_t mutex; // Controle da secao critica
12 sem_t wlock; // Controle do buffer cheio
13 int num_readers = 0;
14
15 void *writer(void *p) {
16 cout << "Escritor criado" << endl;
17 sem_wait (&wlock );
18 cout << "Escritor escrevendo ..." << endl;
19 usleep(rand ()%100);
20 cout << "Escritor terminou de escrever ..." << endl;
21 sem_post (&wlock );
22 }
23
24 void *reader(void *p) {
25 cout << "Leitor criado" << endl;
26
27 sem_wait (&mutex );
28 cout << "Leitor Entrado em processo de leitura ..." << endl;
Problema do leitor-escritor
29 num_readers ++;
30 if(num_readers ==1) sem_wait (&wlock );
31 sem_post (&mutex );
32
33 usleep(rand ()%100);
34
35 sem_wait (&mutex );
36 num_readers --;
37 if(num_readers ==0) sem_post (&wlock );
38 cout << "Leitor liberando leitura ..." << endl;
39 sem_post (&mutex );
40 }
41
42 int main() {
43 pthread_t tmp;
44
45 srand(time(NULL ));
46
Problema do leitor-escritor
47 sem_init (&mutex ,0 ,1);
48 sem_init (&wlock ,0 ,1);
49
50 while (1) {
51 if(rand ()%100 < 50) {
52 pthread_create (&tmp ,NULL ,writer ,NULL);
53 }else{
54 pthread_create (&tmp ,NULL ,reader ,NULL);
55 }
56 }
57
58 return 0;
59 }

Outros materiais