Condividi tramite


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. La funzione Concurrency::wait e la classe Concurrency::Context 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.

SuggerimentoSuggerimento

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

La funzione Concurrency::wait restituisce l'esecuzione del contesto corrente in modo cooperativo per il numero di millisecondi specificato. 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

La classe Concurrency::Context fornisce un'astrazione di programmazione per un contesto di esecuzione e offre due funzionalità principali: la possibilità di bloccare, sbloccare e restituire il contesto corrente in modo cooperativo e la possibilità di abilitare l'oversubscription nel 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 metodo Concurrency::Context::Block blocca il contesto corrente. Un contesto bloccato restituisce le relative risorse di elaborazione in modo che il runtime possa eseguire altre attività. Il metodo Concurrency::Context::Unblock 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 Concurrency::context_self_unblock se un contesto tenta di sbloccarsi.

Per bloccare e sbloccare in modo cooperativo un contesto, è possibile in genere chiamare Concurrency::Context::CurrentContext per recuperare un puntatore all'oggetto Context associato al thread corrente e salvare 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 Concurrency::context_unblock_unbalanced quando il metodo Context::Block o Context::Unblock viene chiamato consecutivamente senza una chiamata corrispondente all'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 metodo Concurrency::Context::Yield restituisce l'esecuzione in modo tale che il runtime possa eseguire altre attività e quindi ripianificare 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

Abilitare l'oversubscription solo da un thread non-UMS creato dal runtime di concorrenza. L'oversubscription non ha effetto quando viene chiamato da un thread non creato dal runtime (incluso il thread principale). Inoltre, l'oversubscription non ha effetto quando viene chiamato da un contesto che utilizza thread UMS per pianificare le attività poiché i thread UMS consentono all'utilità di pianificazione di utilizzare pienamente le risorse in presenza di operazioni di blocco.

Per abilitare l'oversubscription nel contesto corrente, chiamare il metodo Concurrency::Context::Oversubscribe con il parametro _BeginOversubscription 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 Concurrency::invalid_oversubscribe_operation se l'oversubscription viene disabilitato prima di essere abilitato.

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 l'oversubscription per compensare la latenza

Concetti

Utilità di pianificazione (runtime di concorrenza)

Altre risorse

Procedura: utilizzare i gruppi di pianificazione per influenzare l'ordine di esecuzione

Procedura: utilizzare la classe Context per implementare una classe semaforo di cooperazione

Cronologia delle modifiche

Data

Cronologia

Motivo

Luglio 2010

Il contenuto è stato riorganizzato.

Miglioramento delle informazioni.