Buscar

03 Problema da exclusão mútua

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 21 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 21 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 21 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
03 - Problema da exclusão mútua
Prof. Laerte M. Rodrigues
laerte.rodrigues@ifmg.edu.br
Exclusão mútua
I Quando processamos dados compartilhados é importante a
sincronização para o acesso ao dado
I Um dado compartilhado sem o seu devido controle sempre
estará corrompido
I Considere o incremento da varíavel x = 0 dado que x = x+1
I Imagine que n threads irão incrementar a variável x
I Espera-se então x = n
Exclusão mútua
I Devido à acesso mútuo desta variável, o valor final pode ser
menor que
I1 #include <pthread.h>
2 #include <iostream >
3
4 #define NUM_THREADS 1000
5
6 using namespace std;
7
8 void *incremento_thread(void *p) {
9 (*( int*)p)+=1;
10 }
11
12 int main() {
13 pthread_t threads[NUM_THREADS ];
14 int *cont = new int;
Exclusão mútua
15
16 for(int i=0;i<NUM_THREADS;i++) {
17 pthread_create (& threads[i],NULL ,incremento_thread ,cont);
18 }
19
20 for(int i=0;i<NUM_THREADS;i++) {
21 pthread_join(threads[i],NULL);
22 }
23
24 cout << "Final de cont: " << *cont << endl;
25
26 return 0;
27 }
I Na prática, as instruções executadas em nível de máquina
são
Exclusão mútua
I LW $s0, 0($t0)
INC $s0
SW $s0, 0($t0)
I O fato do dado ter a necessidade de ser carregado num
registrador, alterado e posteriormente enviado na memória
principal pode existir consistência
I Considere as threads t0 e t1para o incremento
Exclusão mútua
I
t0 LW $s0, 0($t0)
t0 INC $s0
t1 LW $s0, 0($t0)
t1 INC $s0
t0 SW $s0, 0($t0)
t1 SW $s0, 0($t0)
I Esta situação é comum pois as vezes o sistema deverá
executar (independente do contexto) as operações de forma
ordenada
Exclusão mútua
I Seções do código que necessitam deste tipo de
comportamento são chamados de regiões críticas
I Garantir esta consistência é conhecida como problema da
exclusão mútua
Algoritmo de exclusão mútua
I A interface utilizada a partir deste momento serão as duas
rotinas
I void acquireCS(int tid): Solicita o acesso à região crítica
para a thread em questão
I void releaseCS(int tid): Libera o acesso à região crítica
I Ambos os métodos devem ser chamados na ordem acima
I Quando a thread solicitar o acesso à seção crítica e adquiríla, a
sua execução continuará normalmente
I Quando a região crítica estiver no fim, o acesso à ela deve ser
liberado
Algoritmo de exclusão mútua
I Para fins ilustrativos imagine o seguinte cenário
I n Threads serão criadas
I Cada Thread irá requisitar a CS (Critical Section) para ficar um
tempo aleatório dentro dela
I Após liberar a CS, a mesma irá dormir por um tempo aleatório e
requistar novamente
1 #include <pthread.h>
2 #include <iostream >
3 #include <unistd.h>
4 #include <ctime >
5 #include <cstdlib >
6
7 #define NUM_THREADS 3
8
Algoritmo de exclusão mútua
9 using namespace std;
10
11
12 void acquireCS(int tid) {
13 // CS Algorithm
14 }
15
16 void releaseCS(int tid) {
17 // CS Algorithm
18 }
19
20 void *my_thread(void *p) {
21 int id = *(int*)p;
22
23 while (1) {
24 int tsleep = rand() % 10;
25
26 cout << id << " require CS..." << endl;
Algoritmo de exclusão mútua
27 acquireCS(id);
28 cout << id << " in CS for " << tsleep << " secs" << endl;
29 sleep(tsleep );
30 releaseCS(tid);
31 sleep(rand ()%10);
32 }
33 }
34
35 int main() {
36 pthread_t threads[NUM_THREADS ];
37
38 for(int i=0;i<NUM_THREADS;i++) {
39 pthread_create (& threads[i],NULL ,my_thread ,new int(i));
40 }
41
42 for(int i=0;i<NUM_THREADS;i++) {
43 pthread_join(threads[i],NULL);
44 }
Algoritmo de exclusão mútua
45
46 return 0;
47 }
Algoritmo de Peterson
II Este algoritmo para controle da região crítica é feita por uma
variável compartilhada
I A idéia é similar à de 1 banheiro
I Entra somente 1 por vez
1 bool openDoor;
2
3 void acquireCS(int tid) {
4 while (! openDoor );
5 openDoor = false;
6 }
7
8 void releaseCS(int tid) {
9 openDoor = true;
10 }
Algoritmo de Peterson
II Neste caso, a varíavel openDoor pode não ser atribuída
corretamente
I Uma forma de resolver este problema é criar uma varíavel
que armazena o “interesse” de cada thread em entrar na CS
I Este método, apriori, é feito para 2 threads apenas
1 bool wantCS [] = { false , false };
2
3 void acquireCS(int tid) {
4 wantCS[tid] = true;
5 while(wantCS[1-tid]);
6 }
7
8 void releaseCS(int tid) {
9 wantCS[tid] = false;
10 }
Algoritmo de Peterson
II Ineficiente pois é passível de deadlock
I Uma estratégia também que pode ser utilizada sem afetar a
integridade de variáveis compartilhadas é o uso de turnos
I Cada thread terá a sua “vez” para entrar na CS
1 int turn = 0;
2
3 void acquireCS(int tid) {
4 while(turn%NUM_THREADS != tid);
5 }
6
7 void releaseCS(int tid) {
8 turn ++;
9 }
II Garante a integridade da variável turn
Algoritmo de Peterson
I Somente é alterada quando a CS for liberada
I Passível de inanição
I Para evitar o efeito de inanição para 2 threads, podemos
utilizar os conceitos de “querer” a região crítica + a idéia de
turno
I1 int turn = 0;
2 bool wantCS [] = { false , false };
3
4 void acquireCS(int tid) {
5 int j = 1 - tid;
6 wantCS[tid] = true;
7 turn = j;
8 while(wantCS[j] && turn == j);
Algoritmo de Peterson
9 }
10
11 void releaseCS(int tid) {
12 wantCS[i] = false;
13 }
I Este algoritmo resolve o problema de inaniação do caso
anterior (uma thread que nunca entra na CS)
I Mas não completamente, pois o fato do acesso à CS ser por
“cavalheirismo” é possível de inanição no início da execução
I Em geral os algoritmos de peterson resolvem “bem”
problemas com apenas 2 threads
I Na prática sempre temos mais de 2 threads em execução
Padaria de Lamport
I Um algoritmo muito utilizado para esta estratégia é o
algoritmo da padaria de Lamport (Lamport’s Bakery)
I Utiliza o conceito de “senha”
I A CS é liberada para a Thread com “menor senha”
I Nem sempre é possível garantir a integridade da senha, logo,
utiliza-se a Thread ID para este fim
Padaria de Lamport
1 bool choosing[NUM_THREADS ];
2 int number[NUM_THREADS ];
3
4 // Inicializa a senha de todas as threads
5 for(int i=0;i<NUM_THREADS;i++) {
6 choosing[i] = false;
7 number[i] = 0;
8 }
9
10 void acquireCS(int tid) {
11 // Passo 1: Retirada da senha
12 choosing[tid] = true;
13
14 for(int j=0;j<NUM_THREADS;j++) {
15 if(number[j] > number[tid]) {
16 number[tid] = number[j];
17 }
18 }
Padaria de Lamport
19
20 number[tid ]++;
21 choosing[tid] = false;
22
23 // Passo 2: Verifica se a thread atual Ãc© a "escolhida"
24 for(int j=0;j<NUM_THREADS;j++) {
25 while(choosing[j]); // Thread na porta para retirar senha
26
27 while(number[j]!=0 && (
28 number[j] < number[tid] ||
29 (number[j] == number[tid] && j < tid )))
30 // Esperar liberar CS
31 ;
32 }
33 }
34
35 void releaseCS(int tid) {
36 number[tid] = 0;
Padaria de Lamport
37 }
II As vantagens da padaria de lamport são
I Nenhuma thread irá entrar em inanição
I Todas as threads competem pela CS
I Somente entra aquela com menor senha e de fato “esperando”
I Problema n integridade da senha é resolvido pela thread de
menor ID

Outros materiais