Oggetti sezione critica

Un oggetto sezione critica fornisce la 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 di 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 di sezione critici forniscono un meccanismo leggermente più veloce ed efficiente per la sincronizzazione di 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 rende utile la protezione di una risorsa condivisa dall'accesso simultaneo. A differenza di un oggetto mutex, non è possibile stabilire se è stata abbandonata una sezione critica.

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 a un primo servizio. Questa modifica aumenta notevolmente le prestazioni per la maggior parte del codice. Tuttavia, alcune applicazioni dipendono dall'ordinamento fiFO (first-in, first-out) e possono essere eseguite male o meno in tutte le versioni correnti di Windows (ad esempio, le applicazioni che usano sezioni critiche come limite di frequenza). Per assicurarsi che il codice continui a funzionare correttamente, potrebbe essere necessario aggiungere un livello aggiuntivo di sincronizzazione. Si supponga, ad esempio, di avere un thread producer e un thread consumer che usano un oggetto sezione critica per sincronizzare il proprio lavoro. Creare due oggetti evento, uno per ogni thread da usare per segnalare che è pronto per l'altro thread per procedere. Il thread consumer attende che il produttore 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 in una sezione critica vengono aggiunti a una coda di attesa; si sono svegliati e 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 svegliare ogni thread in attesa.

Il processo è responsabile dell'allocazione della memoria utilizzata 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 in modo indefinito 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 possiede una sezione critica, può effettuare chiamate aggiuntive a EnterCriticalSection o TryEnterCriticalSection senza bloccare l'esecuzione. Ciò impedisce a un thread di deadlock se stesso durante l'attesa di una sezione critica già proprietaria. Per rilasciare 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 spin 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 al sonno. Nei sistemi a processore singolo il conteggio di spin viene ignorato e il conteggio di spin della sezione critica è impostato su 0 (zero). Nei sistemi multiprocessore, se la sezione critica non è disponibile, il thread chiamante spins 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 spin, 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 l'oggetto sezione critica viene inizializzato. Dopo aver chiamato questa funzione, l'oggetto sezione critica non può essere usato 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 a eseguire.

Oggetti Mutex

Uso di oggetti di sezione critici