No Linux, os semáforos são um primitivo de sincronização usado para controlar o acesso a recursos compartilhados por vários processos ou threads. Eles atuam essencialmente como contadores que podem ser incrementados (usando `sem_post`) e decrementos (usando` sem_wait`). Essas operações são atômicas, o que significa que são ininterruptas, garantindo consistência.
Aqui está um detalhamento de suas principais características e uso:
*
Mecanismo de sincronização: Os semáforos impedem as condições de raça, onde vários processos que tentam acessar e modificar o mesmo recurso simultaneamente podem levar a resultados imprevisíveis e incorretos. Eles aplicam uma ordem de acesso controlada.
*
Valor do contador: Um semáforo mantém um valor inteiro não negativo. Este valor representa o número de recursos ou licenças disponíveis.
*
`sem_wait ()` (ou `sem_trywait ()`): Esta operação diminui o valor do semáforo. Se o valor for maior que zero, é diminuído e o processo continuará. Se o valor for zero, o processo bloqueará (aguarda) até que o valor do semáforo se torne maior que o zero (outro processo o incrementa usando `sem_post`). `sem_trywait ()` é uma versão não bloqueadora; Ele retorna um erro se o valor do semáforo for zero.
*
`sem_post ()`: Esta operação incrementa o valor do semáforo. Se um processo estiver bloqueado à espera do semáforo, um dos processos de espera será despertado.
*
Tipos: O Linux fornece semáforos nomeados e sem nome.
*
semáforos sem nome: Eles são criados usando `sem_init ()` e são acessíveis apenas dentro do processo ou grupo de threads onde foram criados. Eles geralmente são usados para sincronização em um único processo.
*
Nomeado semáforos: Eles são criados usando `sem_open ()` e existem na memória compartilhada do sistema. Eles podem ser acessados por vários processos, permitindo a comunicação entre processos (IPC). Os semáforos nomeados são identificados por um nome exclusivo.
*
Semáforos binários: Um semáforo com um valor máximo de 1 é frequentemente chamado de semáforo binário. Ele age como um bloqueio mutex (exclusão mútua), permitindo que apenas um processo acesse o recurso compartilhado por vez.
*
Contagem de semáforos: Um semáforo com um valor maior que 1 é um semáforo de contagem. Ele pode representar várias instâncias de um recurso, permitindo que vários processos acessem o recurso simultaneamente até o valor do semáforo.
Exemplo (conceitual): Imagine uma impressora compartilhada por vários processos. Um semáforo de contagem pode ser usado para controlar o acesso:
1.
Inicialização: O semáforo é inicializado com o número de impressoras (por exemplo, 3).
2.
Processo 1 quer imprimir: Ele chama `sem_wait ()`. O valor de semáforo é diminuído (3 se torna 2) e o processo passa a imprimir.
3.
Processo 2 quer imprimir: Ele chama `sem_wait ()`. O valor de semáforo é diminuído (2 se torna 1) e o processo passa a imprimir.
4.
Processo 3 quer imprimir: Ele chama `sem_wait ()`. O valor de semáforo é diminuído (1 se torna 0) e o processo passa a imprimir.
5.
Processo 4 quer imprimir: Ele chama `sem_wait ()`. O valor do semáforo é 0, portanto o processo bloqueia até que uma impressora fique disponível.
6.
Processo 1 termina a impressão: Ele chama `sem_post ()`. O valor semáforo é incrementado (0 se torna 1) e o processo 4 é despertado.
Bibliotecas de chave: No Linux, os semáforos são normalmente acessados usando as funções POSIX Semaphore declaradas em `
`. Observe que a implementação específica pode variar um pouco entre diferentes sistemas semelhantes a Unix.