Primitivas de sincronização (synchronization primitive), também conhecidas como mecanismos de coordenação, são recursos de software essenciais fornecidos por uma plataforma para facilitar a interação entre threads ou processos. Comumente construídas a partir de operações de baixo nível, como operações atômicas e spinlocks, essas implementações podem se manifestar como mutexes, lock e semaphore. No nível de software, essas abstrações desempenham papéis cruciais, oferecendo controle de fluxo em threads específicas, direcionando o fluxo para workers ou garantindo a exclusividade no processamento de objetos específicos.
Bancos de dados, por exemplo, usam esses conceitos para garantir exclusividade e ordem na escrita de tabelas, e esses locks podem ser consultados com 54.12. pg_locks, por exemplo.
O PHP tem uma sessão inteira de extensões e funções internas para Primitiva de Sincronização PHP: Sync - Manual que vale muito a leitura.
Lock
O conceito de bloqueio em programação refere-se a um mecanismo que permite que apenas um thread tenha acesso a uma determinada seção crítica de código ao mesmo tempo. Ao usar um bloqueio, uma região do código é marcada como exclusiva para o thread que adquire o bloqueio, impedindo que outros threads entrem nessa região simultaneamente.
Por exemplo, em uma academia, há um armário compartilhado por vários usuários. Se alguém já o estiver usando, ele estará trancado, e ninguém mais pode usá-lo até que a pessoa anterior o desbloqueie.
É importante notar que o bloqueio é específico para o processo em execução; isto é, outros processos não têm acesso a esse bloqueio.
Mutex
O termo "mutex" é uma abreviação de "exclusão mútua". Em programação concorrente, um mutex é um mecanismo de sincronização que visa garantir que apenas um thread por vez possa acessar uma seção crítica de código, proporcionando exclusividade no acesso a recursos compartilhados.
Imagine uma situação em que múltiplos threads precisam acessar e modificar os mesmos dados simultaneamente. Sem o uso de um mutex, isso poderia resultar em condições de corrida, onde os threads interferem uns nos outros, levando a resultados inesperados e inconsistências nos dados. O mutex resolve esse problema ao permitir que apenas um thread por vez adquira o acesso exclusivo à seção crítica, enquanto outros aguardam sua vez.
O nome "mutex" destaca a função principal do mecanismo: garantir a "exclusão mútua" entre os threads. Isso significa que, quando um thread adquire um mutex, ele exclui outros threads temporariamente dessa seção crítica, prevenindo conflitos e mantendo a ordem na execução do código.
Ao adquirir um mutex, um thread ganha o direito exclusivo de executar o código dentro da seção crítica. Quando conclui suas operações nessa seção, libera o mutex, permitindo que outros threads possam adquiri-lo e acessar a seção crítica subsequentemente.
Semaphore
Um semáforo restringe o número de usuários simultâneos de um recurso compartilhado até um número máximo. Múltiplos threads podem obter acesso ao recurso (decrementando o semáforo) e sinalizar que concluíram o uso do recurso (incrementando o semáforo).
Por exemplo, imagine que a academia da empresa fornece no máximo 3 cartões de acesso gratuitos diariamente. As três primeiras pessoas que chegarem receberão os cartões de acesso. Se uma quarta pessoa chegar, ela precisará aguardar até que uma das três pessoas anteriores devolva o cartão. O semáforo aqui atua como um mecanismo de controle, garantindo que apenas um número específico de usuários tenha acesso simultâneo ao recurso compartilhado.
Referencias
- Synchronization (computer science)
- Synchronization Primitives
- Overview of synchronization primitives - .NET
- Lock, mutex and semaphore difference
- 8.2. Basic Synchronization Design Patterns — Computer Systems Fundamentals
- PHP: SyncMutex - Manual
- PHP: Sync - Manual
- 13.3. Explicit Locking
- amphp/sync
- The Semaphore Component (Symfony Docs)
- O Jantar dos filósofos - Problema de sincronização em Sistemas Operacionais
Top comments (0)