Compartilhar via


Objetos de seção críticos

Um objeto de seção crítico fornece sincronização semelhante à fornecida por um objeto mutex, exceto que uma seção crítica só pode ser usada pelos threads de um único processo. Objetos de seção críticos não podem ser compartilhados entre processos.

Objetos de evento, mutex e semáforo também podem ser usados em um aplicativo de processo único, mas objetos de seção críticos fornecem um mecanismo um pouco mais rápido e eficiente para sincronização de exclusão mútua (um teste específico do processador e instrução de conjunto). Como um objeto mutex, um objeto de seção crítico pode ser propriedade de apenas um thread por vez, o que o torna útil para proteger um recurso compartilhado contra acesso simultâneo. Ao contrário de um objeto mutex, não há como dizer se uma seção crítica foi abandonada.

A partir do Windows Server 2003 com o Service Pack 1 (SP1), os threads que aguardam em uma seção crítica não adquirem a seção crítica por várias vezes. Essa alteração aumenta significativamente o desempenho para a maioria dos códigos. No entanto, alguns aplicativos dependem da ordenação inicial e inicial (FIFO) e podem ter um desempenho ruim ou não em versões atuais do Windows (por exemplo, aplicativos que têm usado seções críticas como um limitador de taxa). Para garantir que seu código continue funcionando corretamente, talvez seja necessário adicionar um nível adicional de sincronização. Por exemplo, suponha que você tenha um thread de produtor e um thread de consumidor que estão usando um objeto de seção crítico para sincronizar seu trabalho. Crie dois objetos de evento, um para cada thread a ser usado para sinalizar que ele está pronto para que o outro thread prossiga. O thread do consumidor aguardará que o produtor sinalize seu evento antes de entrar na seção crítica e o thread do produtor aguardará o thread do consumidor sinalizar seu evento antes de entrar na seção crítica. Depois que cada thread deixa a seção crítica, ele sinaliza seu evento para liberar o outro thread.

Windows Server 2003 e Windows XP: Threads que estão aguardando uma seção crítica são adicionados a uma fila de espera; eles são acordados e geralmente adquirem a seção crítica na ordem em que foram adicionados à fila. No entanto, se os threads forem adicionados a essa fila a uma taxa rápida o suficiente, o desempenho poderá ser prejudicado devido ao tempo necessário para despertar cada thread de espera.

O processo é responsável por alocar a memória usada por uma seção crítica. Normalmente, isso é feito simplesmente declarando uma variável do tipo CRITICAL_SECTION. Antes que os threads do processo possam usá-lo, inicialize a seção crítica usando a função InitializeCriticalSection ou InitializeCriticalSectionAndSpinCount.

Um thread usa a função EnterCriticalSection ou TryEnterCriticalSection para solicitar a propriedade de uma seção crítica. Ele usa a função LeaveCriticalSection para liberar a propriedade de uma seção crítica. Se o objeto de seção crítica atualmente pertence a outro thread, EnterCriticalSection aguarda indefinidamente pela propriedade. Por outro lado, quando um objeto mutex é usado para exclusão mútua, as funções de espera aceitar um intervalo de tempo limite especificado. A função TryEnterCriticalSection tenta inserir uma seção crítica sem bloquear o thread de chamada.

Quando um thread possui uma seção crítica, ele pode fazer chamadas adicionais para EnterCriticalSection ou TryEnterCriticalSection sem bloquear sua execução. Isso impede que um thread se bloqueie enquanto aguarda uma seção crítica que ele já possui. Para liberar sua propriedade, o thread deve chamar LeaveCriticalSection uma vez para cada vez que ele entrou na seção crítica. Não há garantia sobre a ordem em que os threads de espera adquirirão a propriedade da seção crítica.

Um thread usa a função InitializeCriticalSectionAndSpinCount ou função SetCriticalSectionSepinCount para especificar uma contagem de rotação para o objeto de seção crítico. Girar significa que, quando um thread tenta adquirir uma seção crítica que está bloqueada, o thread entra em um loop, verifica se o bloqueio é liberado e, se o bloqueio não é liberado, o thread entra em suspensão. Em sistemas de processador único, a contagem de rotação é ignorada e a contagem de rotação de seção crítica é definida como 0 (zero). Em sistemas multiprocessadores, se a seção crítica não estiver disponível, o thread de chamada girará dwSpinCount vezes antes de executar uma operação de espera em um semáforo associado à seção crítica. Se a seção crítica se tornar gratuita durante a operação de rotação, o thread de chamada evitará a operação de espera.

Qualquer thread do processo pode usar a função DeleteCriticalSection para liberar os recursos do sistema alocados quando o objeto de seção crítico é inicializado. Depois que essa função é chamada, o objeto de seção crítica não pode ser usado para sincronização.

Quando um objeto de seção crítico é propriedade, os únicos outros threads afetados são os threads que estão aguardando a propriedade em uma chamada para EnterCriticalSection. Os threads que não estão aguardando são gratuitos para continuar em execução.

objetos mutex

usando objetos de seção críticos