Contesti
In questo documento viene descritto il ruolo dei contesti nel runtime di concorrenza.Un thread associato a un'utilità di pianificazione viene definito contesto di esecuzione o semplicemente contesto.Il concurrency::wait funzione e il concurrency::Context classe consentono di controllare il comportamento dei contesti.Utilizzare la funzione wait per sospendere il contesto corrente per un periodo di tempo specificato.Utilizzare la classe Context quando è necessario un maggiore controllo sulle operazioni di blocco, sblocco e restituzione dei contesti e sull'oversubscription nel contesto corrente.
Suggerimento |
---|
Il runtime di concorrenza fornisce un'utilità di pianificazione predefinita, pertanto non è necessario crearne una nell'applicazione.Poiché l'utilità di pianificazione consente di ottimizzare le prestazioni delle applicazioni, è consigliabile iniziare con la PPL (Parallel Patterns Library) o la Libreria di agenti asincroni se non si ha familiarità con il runtime di concorrenza. |
Funzione wait
Il concurrency::wait funzione produce congiuntamente l'esecuzione del contesto corrente per un determinato numero di millisecondi.Il runtime utilizza il tempo di restituzione per eseguire le altre attività.Una volta trascorso il tempo specificato, il runtime ripianifica il contesto per l'esecuzione.Pertanto, la funzione wait potrebbe sospendere il contesto corrente per un tempo maggiore del valore fornito per il parametro milliseconds.
Se si passa 0 (zero) come valore per il parametro milliseconds, il runtime sospenderà il contesto corrente finché tutti gli altri contesti attivi non saranno in grado di eseguire il lavoro.In questo modo, viene restituita un'attività per tutte le altre attività attive.
Esempio
Per un esempio in cui viene utilizzata la funzione wait per restituire il contesto corrente e quindi consentire l'esecuzione di altri contesti, vedere Procedura: utilizzare i gruppi di pianificazione per influenzare l'ordine di esecuzione.
Classe Context
Il concurrency::Context la classe fornisce un'astrazione di programmazione per un contesto di esecuzione e offre due importanti caratteristiche: la possibilità di bloccare, sbloccare e ottenere il contesto corrente congiuntamente e la possibilità di oversubscribe il contesto corrente.
Blocco cooperativo
La classe Context consente di bloccare o restituire il contesto di esecuzione corrente.Il blocco o la restituzione è utile quando il contesto corrente non può continuare poiché una risorsa non è disponibile.
Il concurrency::Context::Block metodo si blocca il contesto corrente.Un contesto bloccato restituisce le relative risorse di elaborazione in modo che il runtime possa eseguire altre attività.Il concurrency::Context::Unblock metodo Sblocca un contesto bloccato.Il metodo Context::Unblock deve essere chiamato da un contesto diverso da quello in cui è stato chiamato Context::Block.Il runtime genera un'eccezione concurrency::context_self_unblock se si tenta di un contesto di sblocco automatico.
Congiuntamente, bloccare e sbloccare un contesto, in genere chiamata concurrency::Context::CurrentContext per recuperare un puntatore ai Context oggetto è associato al thread corrente e Salva il risultato.È possibile quindi chiamare il metodo Context::Block per bloccare il contesto corrente.Successivamente, chiamare Context::Unblock da un contesto separato per sbloccare il contesto bloccato.
È necessario che a ogni chiamata a Context::Block corrisponda una chiamata a Context::Unblock.Il runtime genera un'eccezione concurrency::context_unblock_unbalanced quando la Context::Block o Context::Unblock viene chiamato consecutivamente senza una corrispondente chiamata a un altro metodo.Non è tuttavia necessario chiamare Context::Block prima di chiamare Context::Unblock.Se ad esempio un contesto chiama Context::Unblock prima che un altro contesto chiami Context::Block per lo stesso contesto, tale contesto rimarrà sbloccato.
Il concurrency::Context::Yield metodo sospende l'esecuzione in modo che il runtime può eseguire altre attività e quindi riprogrammare il contesto per l'esecuzione.Quando si chiama il metodo Context::Block il runtime non ripianifica il contesto.
Esempio
Per un esempio in cui vengono utilizzati i metodi Context::Block, Context::Unblock e Context::Yield per implementare una classe semaforo di cooperazione, vedere Procedura: utilizzare la classe Context per implementare una classe semaforo di cooperazione.
Oversubscription
L'utilità di pianificazione predefinita crea un numero di thread pari a quello dei thread di hardware disponibili.È possibile utilizzare l'oversubscription per creare thread aggiuntivi per un thread di hardware specificato.
Per le operazioni più complesse dal punto di vista dell'elaborazione, l'oversubscription non è in genere un'operazione adatta poiché genera un ulteriore sovraccarico.Tuttavia, per le attività che hanno un'eccessiva quantità di latenza, ad esempio la lettura dei dati da disco o da una connessione di rete, l'oversubscription può migliorare l'efficienza complessiva di alcune applicazioni.
[!NOTA]
Attivare oversubscription solo da un thread che è stato creato in fase di esecuzione della concorrenza.L'oversubscription non ha effetto quando viene chiamato da un thread non creato dal runtime (incluso il thread principale).
Per attivare oversubscription nel contesto corrente, chiamare il concurrency::Context::Oversubscribe metodo con il _BeginOversubscription parametro impostato su true.Quando si abilita l'oversubscription in un thread creato dal runtime di concorrenza, il runtime creerà un thread aggiuntivo.Dopo il completamento di tutte le attività che richiedono l'oversubscription, chiamare Context::Oversubscribe con il parametro _BeginOversubscription impostato su false.
È possibile abilitare l'oversubscription più volte dal contesto corrente, ma è necessario disabilitarlo lo stesso numero di volte in cui viene abilitato.L'oversubscription può inoltre essere annidato, ovvero un'attività creata da un'altra attività che utilizza l'oversubscription può abilitare l'oversubscription nel relativo contesto.Tuttavia, se un'attività annidata e la relativa attività padre appartengono entrambe allo stesso contesto, solo la chiamata più esterna a Context::Oversubscribe comporta la creazione di un thread aggiuntivo.
[!NOTA]
Il runtime genera un'eccezione concurrency::invalid_oversubscribe_operation se oversubscription viene disattivato prima è attivata.
Esempio
Per un esempio in cui viene utilizzato l'oversubscription per compensare la latenza causata dalla lettura dei dati da una connessione di rete, vedere Procedura: utilizzare l'oversubscription per compensare la latenza.
Vedere anche
Attività
Procedura: utilizzare i gruppi di pianificazione per influenzare l'ordine di esecuzione
Procedura: utilizzare la classe Context per implementare una classe semaforo di cooperazione
Procedura: utilizzare l'oversubscription per compensare la latenza