Condividi tramite


Strutture di dati di sincronizzazione

Il runtime di concorrenza fornisce diverse strutture dei dati che consentono di sincronizzare l'accesso ai dati condivisi da più thread.Queste strutture dei dati sono utili in presenza di dati condivisi che vengono modificati raramente.Un oggetto di sincronizzazione, ad esempio una sezione critica, impone agli altri thread di attendere finché la risorsa condivisa non è disponibile.Pertanto, se si utilizza tale oggetto per sincronizzare l'accesso ai dati utilizzati di frequente, è possibile perdere scalabilità nell'applicazione.Il PPL (Parallel Patterns Library) fornisce il concurrency::combinable classe, che consente di condividere una risorsa tra più thread o attività senza la necessità di sincronizzazione.Per ulteriori informazioni sulla classe combinable, vedere Contenitori e oggetti paralleli.

Sezioni

In questo argomento vengono descritti in dettaglio i tipi di blocco dei messaggi asincroni seguenti:

  • critical_section

  • reader_writer_lock

  • scoped_lock e scoped_lock_read

  • event

critical_section

Il concurrency::critical_section classe rappresenta un oggetto di esclusione reciproca cooperative che produce per altre attività invece di interruzione li.Le sezioni critiche sono utili quando più thread richiedono l'accesso esclusivo in lettura e scrittura ai dati condivisi.

La classe critical_section non è rientrante.Il concurrency::critical_section::lock metodo genera un'eccezione di tipo concurrency::improper_lock se viene chiamato dal thread che è già proprietario del blocco.

Dd492638.collapse_all(it-it,VS.110).gifMetodi e funzionalità

Nella tabella seguente vengono illustrati i metodi principali definiti dalla classe critical_section.

Metodo

Descrizione

blocco

Acquisisce la sezione critica.Il contesto di chiamata viene bloccato finché non viene acquisito il blocco.

try_lock

Tenta di acquisire la sezione critica, senza bloccarsi.

unlock

Rilascia la sezione critica.

Top

reader_writer_lock

Il concurrency::reader_writer_lock classe fornisce le operazioni di lettura/scrittura di thread-safe ai dati condivisi.Utilizzare i blocchi reader/writer quando più thread richiedono l'accesso in lettura simultaneo a una risorsa condivisa ma raramente scrivono nella risorsa condivisa.Questa classe concede a un oggetto sempre un solo accesso in scrittura al thread.

Le prestazioni della classe reader_writer_lock risultano migliori della classe critical_section poiché un oggetto critical_section acquisisce l'accesso esclusivo a una risorsa condivisa impedendo l'accesso in lettura simultaneo.

Analogamente alla classe critical_section, la classe reader_writer_lock rappresenta un oggetto cooperativo a esclusione reciproca che viene passato ad altre attività anziché annullarle.

Quando un thread che deve scrivere in una risorsa condivisa acquisisce un blocco reader/writer, gli altri thread che devono accedere alla risorsa vengono bloccati finché il writer non rilascia il blocco.La classe reader_writer_lock è un esempio di blocco con preferenza di scrittura, ovvero un blocco che sblocca i writer in attesa prima di sbloccare i reader in attesa.

Analogamente alla critical_section, la classe reader_writer_lock non è rientrante.Il concurrency::reader_writer_lock::lock e concurrency::reader_writer_lock::lock_read metodi generano un'eccezione di tipo improper_lock se vengono chiamati da un thread già proprietario del blocco.

[!NOTA]

Poiché la classe reader_writer_lock non è rientrante, non è possibile aggiornare un blocco di sola lettura a un blocco di lettura/scrittura o declassare un blocco di lettura/scrittura a un blocco di sola lettura.L'esecuzione di entrambe queste operazioni produce un comportamento non specificato.

Dd492638.collapse_all(it-it,VS.110).gifMetodi e funzionalità

Nella tabella seguente vengono illustrati i metodi principali definiti dalla classe reader_writer_lock.

Metodo

Descrizione

blocco

Acquisisce l'accesso in lettura/scrittura al blocco.

try_lock

Tenta di acquisire l'accesso in lettura/scrittura al blocco, senza bloccarsi.

lock_read

Acquisisce l'accesso in sola lettura al blocco.

try_lock_read

Tenta di acquisire l'accesso in sola lettura al blocco, senza bloccarsi.

unlock

Rilascia il blocco.

Top

scoped_lock e scoped_lock_read

Le classi critical_section e reader_writer_lock forniscono classi di supporto annidate che semplificano il modo di utilizzare gli oggetti a esclusione reciproca.Queste classi di supporto sono note come blocchi con ambito.

Il critical_section classe contiene la concurrency::critical_section::scoped_lock classe.Il costruttore acquisisce l'accesso all'oggetto critical_section fornito, mentre il distruttore rilascia l'accesso a tale oggetto.Il reader_writer_lock classe contiene la concurrency::reader_writer_lock::scoped_lock classe, che è simile a critical_section::scoped_lock, ad eccezione del fatto che gestisce l'accesso in scrittura fornito reader_writer_lock oggetto.Il reader_writer_lock classe contiene inoltre il concurrency::reader_writer_lock::scoped_lock_read classe.Questa classe gestisce l'accesso in lettura all'oggetto reader_writer_lock fornito.

I blocchi con ambito forniscono diversi vantaggi quando si utilizzano gli oggetti critical_section e reader_writer_lock manualmente.In genere, un blocco con ambito viene allocato nello stack.Un blocco con ambito rilascia automaticamente l'accesso al relativo oggetto a esclusione reciproca quando viene eliminato; pertanto, l'oggetto sottostante non viene manualmente sbloccato.Ciò si rivela utile quando una funzione contiene più istruzioni return.I blocchi con ambito possono inoltre consentire di scrivere il codice indipendentemente dalle eccezioni.Quando un'istruzione throw determina la rimozione dello stack, viene chiamato il distruttore di un blocco con ambito attivo e pertanto l'oggetto a esclusione reciproca viene sempre rilasciato correttamente.

[!NOTA]

Quando si utilizzano le classi critical_section::scoped_lock, reader_writer_lock::scoped_lock e reader_writer_lock::scoped_lock_read, non rilasciare manualmente l'accesso all'oggetto a esclusione reciproca sottostante,poiché il runtime può restituire uno stato non valido.

event

Il concurrency::event classe rappresenta un oggetto di sincronizzazione cui stato può essere segnalato o non segnalato.A differenza degli oggetti di sincronizzazione, come le sezioni critiche, il cui scopo è proteggere l'accesso ai dati condivisi, gli eventi sincronizzano il flusso di esecuzione.

La classe event è utile quando un'attività ha completato il lavoro di un'altra attività.Ad esempio, un'attività potrebbe segnalare a un'altra attività di aver letto i dati da una connessione di rete o da un file.

Dd492638.collapse_all(it-it,VS.110).gifMetodi e funzionalità

Nella tabella seguente vengono illustrati diversi metodi principali definiti dalla classe event.

Metodo

Descrizione

wait

Attende che l'evento venga segnalato.

set

Imposta l'evento sullo stato segnalato.

reset

Imposta l'evento sullo stato non segnalato.

wait_for_multiple

Attende che più eventi vengano segnalati.

Dd492638.collapse_all(it-it,VS.110).gifEsempio

Per un esempio che illustra come utilizzare la classe event, vedere Confronto delle strutture di dati di sincronizzazione con l'API Windows.

Top

Sezioni correlate