Starvation ocorre quando um processo nunca consegue ser executado devido a um scheduler não funcionar corretamente. Esse problema não é tratado por meio de primitivas e sim pela implementação de um scheduler que escala os processos conseguindo garantir execução a todos.

O livelock ocorre quando dois processos ficam alternando o controle da CPU entre si, assim ambos continuam vivos tentando entrar em execução e passando o controle sobre a CPU e assim nenhum dos dois executam. Esse problema também não é tratado já que depende de “sorte”.

O deadlock é similar ao livelock porém os dois processos ficam bloqueados esperando a liberação do recurso. As condições para que ocorra um deadlock são:

  • Dois ou mais processos compartilham duas ou mais regiões críticas.
  • Existe intersecção de regiões críticas.
  • Formação de ciclo de espera.
  • Ausência de preempção.

O deadlock pode ser resolvido por meio do algoritmo do avestruz, que pressupõe a raridade do deadlock e diz que basta apenas reiniciar a máquina.

Outro método é o timestamp de cada processo:

  • wait-die: o processo mais velho espera e o mais novo morre
  • wait-wound: o mais velho tenta executar e o mais novo espera.

The Dining Philosophers

Problema: há 5 filósofos numa mesa circular, cada qual com um garfo entre pares, ou seja, 5 garfos também.

![[Pasted image 20250512101132.png]]

Um filósofo pensa (libera os garfos) e come (usa os garfos). Precisamos identificar os garfos à esquerda e à direita do filósofo (cada um com seu ID próprio). Com:

int left(p) { return p;}
int right(p) { return p + 1) % n;}

A solução é fazer cada um dos filósofos pegar um garfo inicial diferente. Ou seja, o filósofo 4 pega o garfo 0 (direita) enquanto o 0 tenta inicialmente pegar o garfo 0 (esquerda). Assim, se um deles conseguir pegar o garfo, o outro esperará, sem deadlocks possíveis.

Solução

# P = sem_wait()
# V = sem_post()
Philo[i=0 to n-2]{
	while(true){
		P(i);
		P((i+1)%n);
		eat();
		V((i+1)%n);
		V(i);
	}
}
Philo[n-1]{
	while(true){
		think();
		P(0);
		P(n);
		eat();
		V(n);
		V(0);
	}
}

Problema dos Fumantes (Smoker Problem)

problema

O Problema dos Macacos (baboon crossing)

Suponha que haja macacos em ambas as margens de um rio e, de tempos em tempos, os macacos decidem passar para o outro lado à procura de comida. A passagem para a outra margem do rio é feita através de uma ponte de corda. Mais de um macaco pode atravessar a ponte ao mesmo tempo, mas isso só é possível se eles estiverem indo na mesma direção.

Implemente um programa que faça o controle da passagem de macacos pela ponte usando Semáforos. Para testar o sistema, crie 10 threads que representem os macacos, colocando inicialmente metade deles em cada margem do rio. Sempre que um macaco iniciar ou concluir a travessia, imprima uma mensagem na tela identificando o macaco.

Após testar o programa acima, crie agora uma nova verão do programa adicionando dois gorilas, um de cada lado do rio. Como os gorilas são muito pesados, eles só poderão atravessar a ponte sozinhos. Como os outros macacos têm medo dos gorilas, eles terão prioridade para fazer a travessia.

Problema do banheiro unissex

Declaração do Problema:

Um banheiro está sendo projetado para uso de homens e mulheres em um escritório, mas requer que as seguintes restrições sejam mantidas:

  • Não pode haver homens e mulheres no banheiro ao mesmo tempo.
  • Nunca deve haver mais de três funcionários no banheiro simultaneamente.
  • Não deve haver inanição.
Process banheiro() {
	P(Pessoa)
	usaBanheiro()
}

process homem() {
	while(true) {
		P(Banheiro)
		P(Mulher)
		pessoa = "homem"
		V(Pessoa)
		V(Mulher)
		V(Banheiro)
	}
}

process mulher() {
	while(true) {
		P(Banheiro)
		P(Homem)
		pessoa = "mulher"
		V(Pessoa)
		V(Homem)
		V(Banheiro)
	}
}

Problema do Barbeiro Dorminhoco

O problema se resume a um barbeiro que seria o processo e clientes que são outros processos, assim o corte de cabelo é determinado por meio do barbeiro que quando tem cliente realiza o corte e quando termina chama outro cliente ou dorme (entra no estado de bloqueado).

Barbeiro

Dorme se não tem cliente. Se tem cliente:

  • Chama para cortar
  • espera ele sentar
  • faz o corte, avisa no final
  • espera o cliente sair

Cliente

  • Acorda o barbeiro se precisar
  • Espera o barbeiro chamar
  • Seguem instruções do Barbeiro
  • saem após o corte

sem B = 1;
sem C = 1;
sem corte = 1;
sem saida = 1;
sem cad = 1;

Process Barber{
	while(true){
			P(C);     // Espera Cliente
			V(B);     // Libera Barbeiro
			P(cad);   // Espera Cadeira
			corta();
			V(corte); // Libera Corte
			P(saida); // Espera saída
	}
}

Process Client[i=1 to N]{
	while(true){
		V(C);     // Aumenta cliente
		P(B);     // Espera Barbeiro
		V(cad);   // Semaforo Cadeira
		P(corte); // Espera corte
		V(saida); // Espera Saida
	}
}

notas: processo é tratado como thread. cliente produz clientes, ou seja, quando chega um cliente o barbeiro é liberado. o cliente então espera ter barbeiros possíveis, se tiver, ele aumenta o numero de cadeira usadas. ai o barbeiro espera a cadeira aparecer, qnd tiver ele corta o cabelo e libera o semaforo de corte, que o cliente estava esperando. ai sim o barbeiro espera a saida do cliente