- P(S) : se S >= 1 então S:=S-1
- senão Bloqueie o processo na fila do semáforo
- V(S) : se algum processo está bloqueado no semáforo S
- então desbloquear o processo
- senão S:=S+1
Um semáforo é uma estrutura de dados que consiste em um número inteiro e em uma fila que armazena descritores de tarefas. O conceito de semáforos consiste na colocação de proteções (guardas) em torno do código que acessa esta estrutura para oferecer acesso limitado aos dados [SEB 00]. Em geral, a estrutura de dados é uma fila, funcionando em regime de primeiro-a-entrar / primeiro a sair [GHE 91].
O semáforo é um mecanismo simples que pode ser usado para oferecer sincronismo de tarefas [SEB 00]. As operações em tipos de semáforos, muitas vezes não são diretas, elas são feitas por subprogramas de espera (wait) e de liberação (release).
Há um problema em semáforos, o deadlock. Este ocorre quando um processo altera o valor do semáforo e entra na região crítica, mas ocorre uma falha na saída da região porque ele foi danificado ou morto.
Em 1965 Dijkstra introduziu a noção de semáforo para impor a exclusão mútua entre processos. É uma construção de alto nível também usada para sincronizar processos. Um semáforo S é uma variável inteiro positiva sobre a qual os processos podem fazer duas operações primitivas (indivisíveis) - P(S) e V(S). P e V têm sua origem das palavras parsen (passar) e e vrygeren (liberar)). Uma vez iniciada uma das operações ela irá até o fim sem interrupções. Cada semáforo tem uma fila associada a ele, onde processos bloqueados nele esperam. As operações P e V são definidas como segue:
Quando uma operação V(S) é executada, um processo bloqueado é retirado da fila para execução. A disciplina de empilhamento da fila do semáforo depende da implementação. Dependendo dos valores que o semáforo pode ter, há dois tipos:
O semáforo é inicializado pelo sistema. Semáforos Binários são usados para criar exclusão mútua no acesso a recursos com uma unidade apenas, porque apenas um processo pode passar pela operação P a cada vez. Semáforos de contagem são utilizados para sincronização e controle de alocação de recursos com mais de uma unidade. O valor inicial do semáforo é igual ao número de unidades do recurso.
Java não implenta explicitamente semáforos, mas fornece meios para que ele possa ser implementado. Veja um exemplo de implementção de uma classe Semaphore.