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.
Metodi e funzionalità
Nella tabella seguente vengono illustrati i metodi principali definiti dalla classe critical_section.
Metodo |
Descrizione |
---|---|
Acquisisce la sezione critica.Il contesto di chiamata viene bloccato finché non viene acquisito il blocco. |
|
Tenta di acquisire la sezione critica, senza bloccarsi. |
|
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.
Metodi e funzionalità
Nella tabella seguente vengono illustrati i metodi principali definiti dalla classe reader_writer_lock.
Metodo |
Descrizione |
---|---|
Acquisisce l'accesso in lettura/scrittura al blocco. |
|
Tenta di acquisire l'accesso in lettura/scrittura al blocco, senza bloccarsi. |
|
Acquisisce l'accesso in sola lettura al blocco. |
|
Tenta di acquisire l'accesso in sola lettura al blocco, senza bloccarsi. |
|
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.
Metodi e funzionalità
Nella tabella seguente vengono illustrati diversi metodi principali definiti dalla classe event.
Metodo |
Descrizione |
---|---|
Attende che l'evento venga segnalato. |
|
Imposta l'evento sullo stato segnalato. |
|
Imposta l'evento sullo stato non segnalato. |
|
Attende che più eventi vengano segnalati. |
Esempio
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
Confronto delle strutture di dati di sincronizzazione con l'API Windows
Viene confrontato il comportamento delle strutture dei dati di sincronizzazione con quelle fornite dall'API Windows.Runtime di concorrenza
Viene descritto il runtime di concorrenza che semplifica la programmazione parallela e vengono forniti i collegamenti ad argomenti correlati.