Oggetti sezione critica

Un oggetto sezione critica fornisce una sincronizzazione simile a quella fornita da un oggetto mutex, ad eccezione del fatto che una sezione critica può essere usata solo dai thread di un singolo processo. Gli oggetti sezione critica non possono essere condivisi tra processi.

Gli oggetti evento, mutex e semaforo possono essere usati anche in un'applicazione a processo singolo, ma gli oggetti sezione critica forniscono un meccanismo leggermente più veloce ed efficiente per la sincronizzazione dell'esclusione reciproca (un test specifico del processore e un'istruzione set). Come un oggetto mutex, un oggetto sezione critica può essere di proprietà di un solo thread alla volta, che lo rende utile per proteggere una risorsa condivisa dall'accesso simultaneo. A differenza di un oggetto mutex, non è possibile stabilire se una sezione critica è stata abbandonata.

A partire da Windows Server 2003 con Service Pack 1 (SP1), i thread in attesa di una sezione critica non acquisiscono la sezione critica in base alle prime funzionalità. Questa modifica aumenta significativamente le prestazioni per la maggior parte del codice. Tuttavia, alcune applicazioni dipendono dall'ordinamento FIFO (First-In First-In First Out) e potrebbero avere prestazioni scarse o non affatto sulle versioni correnti di Windows (ad esempio, applicazioni che usano sezioni critiche come limite di velocità). Per garantire che il codice continui a funzionare correttamente, potrebbe essere necessario aggiungere un ulteriore livello di sincronizzazione. Si supponga, ad esempio, di avere un thread producer e un thread consumer che usano un oggetto sezione critica per sincronizzare il lavoro. Creare due oggetti evento, uno per ogni thread da usare per segnalare che l'altro thread può continuare. Il thread consumer attenderà che il producer segnali l'evento prima di immettere la sezione critica e il thread producer attenderà che il thread consumer segnali l'evento prima di immettere la sezione critica. Dopo che ogni thread lascia la sezione critica, segnala l'evento per rilasciare l'altro thread.

Windows Server 2003 e Windows XP: i thread in attesa di una sezione critica vengono aggiunti a una coda di attesa, ma in genere acquisiscono la sezione critica nell'ordine in cui sono stati aggiunti alla coda. Tuttavia, se i thread vengono aggiunti a questa coda a una velocità sufficiente, le prestazioni possono essere ridotte a causa del tempo necessario per risvegliare ogni thread in attesa.

Il processo è responsabile dell'allocazione della memoria usata da una sezione critica. In genere, questa operazione viene eseguita semplicemente dichiarando una variabile di tipo CRITICAL_SECTION. Prima che i thread del processo possano usarlo, inizializzare la sezione critica usando la funzione InitializeCriticalSection o InitializeCriticalSectionAndSpinCount .

Un thread usa la funzione EnterCriticalSection o TryEnterCriticalSection per richiedere la proprietà di una sezione critica. Usa la funzione LeaveCriticalSection per rilasciare la proprietà di una sezione critica. Se l'oggetto sezione critica è attualmente di proprietà di un altro thread, EnterCriticalSection attende indefinitamente la proprietà. Al contrario, quando un oggetto mutex viene usato per l'esclusione reciproca, le funzioni di attesa accettano un intervallo di timeout specificato. La funzione TryEnterCriticalSection tenta di immettere una sezione critica senza bloccare il thread chiamante.

Quando un thread è proprietario di una sezione critica, può effettuare chiamate aggiuntive a EnterCriticalSection o TryEnterCriticalSection senza bloccarne l'esecuzione. Ciò impedisce a un thread di bloccarsi durante l'attesa di una sezione critica già proprietaria. Per rilasciarne la proprietà, il thread deve chiamare LeaveCriticalSection una volta per ogni volta che ha immesso la sezione critica. Non esiste alcuna garanzia sull'ordine in cui i thread in attesa acquisiranno la proprietà della sezione critica.

Un thread usa la funzione InitializeCriticalSectionAndSpinCount o SetCriticalSectionSpinCount per specificare un conteggio di rotazioni per l'oggetto sezione critica. La rotazione indica che quando un thread tenta di acquisire una sezione critica bloccata, il thread entra in un ciclo, verifica se il blocco viene rilasciato e se il blocco non viene rilasciato, il thread passa alla sospensione. Nei sistemi a processore singolo, il conteggio delle rotazioni viene ignorato e il numero di rotazioni della sezione critica è impostato su 0 (zero). Nei sistemi multiprocessore, se la sezione critica non è disponibile, il thread chiamante ruota dwSpinCount volte prima di eseguire un'operazione di attesa su un semaforo associato alla sezione critica. Se la sezione critica diventa libera durante l'operazione di selezione, il thread chiamante evita l'operazione di attesa.

Qualsiasi thread del processo può usare la funzione DeleteCriticalSection per rilasciare le risorse di sistema allocate quando viene inizializzato l'oggetto sezione critica. Dopo la chiamata a questa funzione, non è possibile utilizzare l'oggetto sezione critica per la sincronizzazione.

Quando un oggetto sezione critica è di proprietà, gli unici thread interessati sono i thread in attesa della proprietà in una chiamata a EnterCriticalSection. I thread che non sono in attesa sono liberi di continuare l'esecuzione.

Oggetti Mutex

Utilizzo di oggetti sezione critica