1. Conceito
Um semáforo é uma variável de sincronização manipulada por operações atômicas. Em sua forma mais simples, um semáforo binário possui valor 1 quando o recurso está disponível e 0 quando está ocupado.
2. Estado do semáforo
Recurso disponível. Um processo pode executar wait(S).
3. Processos, fila e seção crítica
4. O que acontece a cada operação?
5. Semáforo binário x contador
Capacidade do recurso
6. Pseudocódigo clássico
// semáforo inicialmente livre semaphore S = 1; processo() { wait(S); // tenta entrar // ===== SEÇÃO CRÍTICA ===== acessar_recurso_compartilhado(); signal(S); // libera o recurso }
7. Exemplo conceitual em JavaScript
class Semaphore { constructor(value = 1) { this.value = value; this.queue = []; } async wait() { if (this.value > 0) { this.value--; return; } await new Promise(resolve => this.queue.push(resolve) ); } signal() { const next = this.queue.shift(); next ? next() : this.value++; } }
Observação: JavaScript no navegador não é um sistema operacional, mas o padrão acima ajuda a visualizar a mesma ideia de controlar concorrência em tarefas assíncronas.
8. Relação com os estados de processos do S.O.
Quando um processo chama wait(S) e o recurso está indisponível, ele não precisa ficar gastando CPU verificando continuamente o semáforo. O sistema pode colocá-lo no estado Blocked. Quando outro processo chama signal(S), um processo bloqueado pode voltar para Ready e, posteriormente, ser escalonado para Running.