Concorrência:
Sincronização de fina granularidade
André Santos
CIn-UFPE
©André Santos, 1998-2000
Busy Waiting



Tipo de sincronização em que um
processo continuamente verifica uma
condição até que ela se torne
verdadeira
Pode ser implementada com o conjunto
de instruções de qualquer processador
moderno
Ineficiente para multiprogramação
©André Santos,
1998-2000
Busy waiting


Utilizado em dispositivos de hardware
multiprocessados
Pode ser usado para implementar
await
©André Santos,
1998-2000
O Problema da Exclusão
Mútua (Região Crítica)

N processos executam um loop infinito:
 Seção crítica
 Seção não crítica

O programa deve satisfazer a
propriedade de exclusão mútua
 instruções das regiões críticas de dois ou
mais processos não podem ser
executadas ao mesmo tempo.
©André Santos,
1998-2000
Exclusão Mútua para N
processos

N processos executando loop infinito
 Seção crítica
 Seção não crítica

Programa deve satisfazer a propriedade
de exclusão mútua
 Em um dado instante no máximo um
processo está executando sua região
crítica.
©André Santos,
1998-2000
solução: instruções adicionais


protocolo de entrada e de saída
P[i: 1..n]:: while (TRUE) {
entry protocol
critical section
exit protocol
non-critical section
}
©André Santos,
1998-2000
outras condições


um processo pode parar ou terminar
fora da região crítica, sem interferir com
outros processos.
Ausência de deadlock (ou livelock)
 se dois ou mais processos tentam entrar
em sua região crítica, um deles deve
conseguir.
©André Santos,
1998-2000
Outras condições

Ausência de espera desnecessária
 Se um processo quer entrar em sua região
crítica e os outros processos estão fora da
sua região crítica ou terminaram, ele não
será impedido de entrar

Entrada eventual (ausência de
starvation)
 se um processo quer entrar na região
crítica, em algum momento ele entrará.
©André Santos,
1998-2000
Tentativa 1: variável Turn

int Turn = 1;
void P1() {
void P2() {
while (TRUE) {
while (TRUE) {
/* Non_Cr_S_1 */
/* Non_Cr_S_2 */
while (Turn != 1) {}; while (Turn != 2) {};
/* Crit_S_1 */
/* Crit_S_2 */
Turn = 2;
Turn = 1;
}
}
}
}
©André Santos,
1998-2000
Verificação da solução

A solução satisfaz o requisito de
exclusão mútua
 assuma que ela não satisfaz 
contradição

A solução não entra em deadlock
 assuma que o programa está em deadlock
 contradição
©André Santos,
1998-2000
Verificação da solução

Não há starvation
 ao sair da região crítica cada processo
passa a vez ao outro
©André Santos,
1998-2000
Verificação da solução

A solução pode falhar se um processo
parar fora da região crítica
 se um processo pára em sua região não
crítica, o outro não pode prosseguir.


Corrotinas
Execução “sincronizada”
©André Santos,
1998-2000
Tentativa 2: 2 variáveis

int In1, In2 = FALSE;
void P1 () {
void P2 () {
while (TRUE)
while (TRUE)
{ Non_Cr_S_1;
{ Non_Cr_S_2;
while (In2) {};
while (In1) {};
In1 = TRUE;
In2 = TRUE;
Crit_S_1;
Crit_S_2;
In1 = FALSE;
In2 = FALSE;
}
}
}
}
©André Santos,
1998-2000
Verificação da solução

P1 e P2 podem entrar na seção crítica
simultaneamente






P1 verifica In2 e encontra In2 = FALSE
P2 verifica In1 e encontra In1 = FALSE
P1 seta In1 para TRUE
P2 seta In2 para TRUE
P1 entra na seção crítica
P2 entra na seção crítica
©André Santos,
1998-2000
Tentativa 3:

Int In1, In2 = FALSE;
void P1 () {
void P2() {
while (TRUE)
while (TRUE)
{ Non_Cr_S_1;
{ Non_Cr_S_2;
In1 = TRUE;
In2 = TRUE;
while (In2) {};
while (In1) {};
Crit_S_1;
Crit_S_2;
In1 = FALSE;
In2 = FALSE;
}
}
}
}
©André Santos,
1998-2000
Verificação da solução

A solução satisfaz a propriedade de
exclusão mútua
©André Santos,
1998-2000
Verificação da solução

A solução pode entrar em deadlock




P1 atribui TRUE a In1
P2 atribui TRUE a In2
P1 testa In2 e fica no loop
P2 testa In1 e fica no loop
©André Santos,
1998-2000
Tentativa 4: passando a vez

Int In1, In2 = 1;
void P1 () {
while (TRUE)
{ Non_Cr_S_1;
In1 = TRUE;
while (In2)
{ In1 = FALSE;
In1 = TRUE;
};
Crit_S_1;
In1 = FALSE;
}
}
void P2 () {
while (TRUE)
{ Non_Cr_S_2;
In2 = TRUE;
while (In1)
{ In2 = FALSE;
In2 = TRUE;
};
Crit_S_2;
In2 = FALSE;
}
}
©André Santos,
1998-2000
Verificação da solução

Um processo pode ser starved




P1 seta In1 para TRUE
P2 seta In2 para TRUE
P2 verifica In1 e seta In2 para FALSE
P1 faz um ciclo completo: verifica In2,
entra na região crítica, seta In1 para
FALSE, executa região não-crítica, seta
In1 para TRUE
 P2 seta In2 para TRUE...
©André Santos,
1998-2000
Verificação da solução



A solução pode entrar em livelock
deadlock: nenhuma sequência resulta
em sucesso
livelock: existe uma ou mais sequências
que evita que os processos entrem na
região crítica
©André Santos,
1998-2000
Entretanto...


É possível inserir um delay entre as
mudanças nas variáveis, para aumentar
a possibilidade de context-switch
ocorrer com variável alterada.
Uso prático: algorítimo semelhante é
usado em redes Ethernet
©André Santos,
1998-2000
Solução Ideal 1

int In1, In2 = FALSE;
void P1 () {
void P2 () {
while (TRUE)
while (TRUE)
{ Non_Cr_S_1;
{ Non_Cr_S_2;
<await not In2 ->
<await not In1 ->
In1 = TRUE;>
In2 = TRUE;>
Crit_S_1;
Crit_S_2;
In1 = FALSE;
In2 = FALSE;
}
}
}
}
©André Santos,
1998-2000
Solução Ideal 2

int lock = FALSE;
void P1 () {
void P2 () {
while (TRUE)
while (TRUE)
{ Non_Cr_S_1;
{ Non_Cr_S_2;
<await not lock ->
<await not Iock ->
lock = TRUE;>
Iock = TRUE;>
Crit_S_1;
Crit_S_2;
lock = FALSE;
lock = FALSE;
}
}
}
}
©André Santos,
1998-2000
Exclusão mútua assistida por
hardware


load e store em uma única instrução
test e set:
 TS(lock, cc) = <cc := lock; lock := true>

Exchange(A,B)
 = <Temp := A; A := B; B := Temp;>
©André Santos,
1998-2000
Exclusão mútua com Test and Set

int lock = FALSE;
void P1 () {
int C1;
while (TRUE)
{ Non_Cr_S_1;
TS (lock,C1);
while (C1) {
TS (lock,C1);
};
Crit_S_1;
lock = FALSE;
}
}
void P2 () {
int C2;
while (TRUE)
{ Non_Cr_S_2;
TS (lock,C2);
while (C2) {
TS (lock,C2);
};
Crit_S_2;
lock = FALSE;
}
}
©André Santos,
1998-2000
Vantagens

Funciona facilmente para vários
processos.
©André Santos,
1998-2000
Desvantagens


Escrita frequente nas variáveis
Todos os processos acessam a mesma
variável lock.
©André Santos,
1998-2000
Exclusão mútua com Exchange

int InCS = FALSE;
void P1 () {
int L1 = TRUE;
while (TRUE)
{ Non_Cr_S_1;
Exchng (L1,InCS);
while (L1) {
Exchng (L1,InCS);
};
Crit_S_1;
Exchng (L1,InCS);
}
}
void P2 () {
int L2 = TRUE;
while (TRUE)
{ Non_Cr_S_2;
Exchng (L2,InCS);
while (L2) {
Exchng (L2,InCS);
};
Crit_S_2;
Exchng (L2,InCS);
}
}
©André Santos,
1998-2000
Download

finegrained1