Quais problemas podem ocorrer quando dois ou mais processos compartilham variáveis?
| P1 | P2 |
|---|---|
| A = 1 | B = 2 |
| P1 | P2 |
|---|---|
| A = B + 1 | B = 2 * B |
| P1 | P2 |
|---|---|
| A = 1 | A = 2 |
Operações Atômicas são operações que não podem ser interrompidas.
| Operações Atômicas | Operações Não-Atômicas |
|---|---|
| tocar a campainha | encher um copo de água |
| desligar a luz | caminhar até a porta |
| Hora | Pessoa A | Pessoa B |
|---|---|---|
| 6:00 | Olha a geladeira: sem leite | - |
| 6:05 | Sai para a padaria | - |
| 6:10 | Chega na padaria | Olha a geladeira: sem leite |
| 6:15 | Sai da padaria | Sai para a padaria |
| 6:20 | Chega em casa: guarda o leite | Chega na padaria |
| 6:25 | - | Sai da padaria |
| 6:30 | - | Chega em casa: Ops! |
Uma solução para o problema envolve dois novos conceitos:
A maioria envolve trancamento (locking):
| Regra | Exemplo da geladeira |
|---|---|
| 1. Trancar antes de utilizar | Deixar aviso |
| 2. Destrancar quando terminar | Retirar o aviso |
| 3. Esperar se estiver trancado | Não sai para comprar se houver aviso |
Processos A e B
if (SemLeite) {
if (SemAviso) {
Deixa Aviso;
Compra Leite;
Remove Aviso;
}
}
Esta "solução" funciona?
Processos A e B
if (SemLeite) {
if (SemAviso) {
Deixa Aviso;
Compra Leite;
Remove Aviso;
}
}
A Solução piora o problema! Agora falha só de vez em quando, ou seja a depuração fica muito mais difícil:
| Processo A | Processo B |
|---|---|
if (SemAviso) {
if (SemLeite) {
Compra Leite;
}
Deixa Aviso;
}
|
if (Aviso) {
if (SemLeite) {
Compra Leite;
}
Remove Aviso;
}
|
| Processo A | Processo B |
|---|---|
Deixa AvisoA;
while (AvisoB);
if (SemLeite) {
Compra Leite;
}
Remove AvisoA;
|
Deixa AvisoB;
if (SemAvisoA) {
if (SemLeite) {
Compra Leite;
}
}
Remove AvisoB;
|
Produtor() {
while (true) {
while (counter == n);
buffer[in] = item_produzido;
in=in+1 mod n;
counter++;
};
};
Consumidor() {
while (true) {
while (counter == 0);
item_consumido = buffer[out];
out=out+1 mod n;
counter--;
};
}
Produtor() {
while (true) {
while (counter == n);
buffer[in] = item_produzido;
in=in+1 mod n;
R1 = [counter];
inc(R1);
[counter] = R1;
};
};
Consumidor() {
while (true) {
while (counter == 0);
item_consumido = buffer[out];
out=out+1 mod n;
R1 = [counter];
dec(R1);
[counter] = R1;
};
}
Produtor() {
while (true) {
while (in+1 mod n == out);
buffer[in] = item_produzido;
in=in+1 mod n;
};
};
Consumidor() {
while (true) {
while (in == out);
item_consumido = buffer[out];
out=out+1 mod n;
};
}
Como escrever uma solução correta que usa n posições do buffer ?
while (!fim) {
secao_nao_critica;
lock();
secao_critica;
unlock();
}