Confronto delle strutture di dati di sincronizzazione con l'API Windows
In questo argomento viene confrontato il comportamento delle strutture di dati di sincronizzazione fornite dal runtime di concorrenza con quelle fornite dall'API Windows.
Le strutture di dati di sincronizzazione fornite dal runtime di concorrenza seguono il modello di threading cooperativo.Nel modello di threading cooperativo, le primitive di sincronizzazione restituiscono in modo esplicito le risorse di elaborazione agli altri thread.Questo modello è diverso dal modello di threading di tipo preemptive, dove le risorse di elaborazione vengono trasferite agli altri thread dall'utilità di pianificazione di controllo o dal sistema operativo.
critical_section
Il concurrency::critical_section classe è simile a Windows CRITICAL_SECTION struttura poiché può essere utilizzato solo dai thread di un processo.Per ulteriori informazioni sulle sezioni critiche nell'API Windows, vedere Oggetti sezione critica (la pagina potrebbe essere in inglese).
reader_writer_lock
Il concurrency::reader_writer_lock classe è simile a blocchi di lettura/scrittura (SRW) di Windows.Nella tabella seguente vengono illustrate similitudini e differenze.
Funzionalità |
reader_writer_lock |
Blocco SRW |
---|---|---|
Non rientrante |
Sì |
Sì |
Possibilità di promuovere da reader a writer (supporto dell'aggiornamento) |
No |
No |
Possibilità di abbassare di livello da writer a reader (supporto del downgrade) |
No |
No |
Blocco preferenza scrittura |
Sì |
No |
Accesso FIFO ai writer |
Sì |
No |
Per ulteriori informazioni sui blocchi SRW, vedere Blocchi in lettura/scrittura ridotti (SRW) (la pagina potrebbe essere in inglese) in Platform SDK.
event
Il concurrency::event classe è simile a un evento di reimpostazione manuale di Windows senza nome.Tuttavia, un oggetto event si comporta in modo cooperativo, mentre un evento Windows si comporta in modo preemptive.Per ulteriori informazioni sugli eventi Windows, vedere Oggetti eventi (la pagina potrebbe essere in inglese).
Esempio
Descrizione
Per comprendere meglio la differenza tra la classe event e gli eventi Windows, considerare l'esempio seguente.Questo esempio consente all'utilità di pianificazione di creare al massimo due attività simultanee, quindi vengono chiamate due funzioni simili che utilizzano la classe event e un evento Windows di reimpostazione manuale.Ogni funzione crea innanzitutto diverse attività in attesa che un evento condiviso venga segnalato.Ogni funzione viene quindi restituita alle attività in esecuzione e segnala l'evento.Ogni funzione attende infine l'evento segnalato.
Codice
// event-comparison.cpp
// compile with: /EHsc
#include <windows.h>
#include <concrtrm.h>
#include <ppl.h>
#include <iostream>
#include <sstream>
using namespace concurrency;
using namespace std;
// Demonstrates the usage of cooperative events.
void RunCooperativeEvents()
{
// An event object.
event e;
// Create a task group and execute five tasks that wait for
// the event to be set.
task_group tasks;
for (int i = 0; i < 5; ++i)
{
tasks.run([&] {
// Print a message before waiting on the event.
wstringstream ss;
ss << L"\t\tContext " << GetExecutionContextId()
<< L": waiting on an event." << endl;
wcout << ss.str();
// Wait for the event to be set.
e.wait();
// Print a message after the event is set.
ss = wstringstream();
ss << L"\t\tContext " << GetExecutionContextId()
<< L": received the event." << endl;
wcout << ss.str();
});
}
// Wait a sufficient amount of time for all tasks to enter
// the waiting state.
Sleep(1000L);
// Set the event.
wstringstream ss;
ss << L"\tSetting the event." << endl;
wcout << ss.str();
e.set();
// Wait for all tasks to complete.
tasks.wait();
}
// Demonstrates the usage of preemptive events.
void RunWindowsEvents()
{
// A Windows event object.
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("Windows Event"));
// Create a task group and execute five tasks that wait for
// the event to be set.
task_group tasks;
for (int i = 0; i < 5; ++i)
{
tasks.run([&] {
// Print a message before waiting on the event.
wstringstream ss;
ss << L"\t\tContext " << GetExecutionContextId()
<< L": waiting on an event." << endl;
wcout << ss.str();
// Wait for the event to be set.
WaitForSingleObject(hEvent, INFINITE);
// Print a message after the event is set.
ss = wstringstream();
ss << L"\t\tContext " << GetExecutionContextId()
<< L": received the event." << endl;
wcout << ss.str();
});
}
// Wait a sufficient amount of time for all tasks to enter
// the waiting state.
Sleep(1000L);
// Set the event.
wstringstream ss;
ss << L"\tSetting the event." << endl;
wcout << ss.str();
SetEvent(hEvent);
// Wait for all tasks to complete.
tasks.wait();
// Close the event handle.
CloseHandle(hEvent);
}
int wmain()
{
// Create a scheduler policy that allows up to two
// simultaneous tasks.
SchedulerPolicy policy(1, MaxConcurrency, 2);
// Attach the policy to the current scheduler.
CurrentScheduler::Create(policy);
wcout << L"Cooperative event:" << endl;
RunCooperativeEvents();
wcout << L"Windows event:" << endl;
RunWindowsEvents();
}
Commenti
Questo esempio produce l'output seguente:
Cooperative event:
Context 0: waiting on an event.
Context 1: waiting on an event.
Context 2: waiting on an event.
Context 3: waiting on an event.
Context 4: waiting on an event.
Setting the event.
Context 5: received the event.
Context 6: received the event.
Context 7: received the event.
Context 8: received the event.
Context 9: received the event.
Windows event:
Context 10: waiting on an event.
Context 11: waiting on an event.
Setting the event.
Context 12: received the event.
Context 14: waiting on an event.
Context 15: received the event.
Context 16: waiting on an event.
Context 17: received the event.
Context 18: waiting on an event.
Context 19: received the event.
Context 13: received the event.
Poiché la classe event si comporta in modo cooperativo, l'utilità di pianificazione può riassegnare le risorse di elaborazione a un altro contesto mentre un evento è in attesa di passare allo stato segnalato.Pertanto, la versione che utilizza la classe event esegue più lavoro.Nella versione che utilizza gli eventi Windows, ogni attività in attesa deve passare allo stato segnalato prima che venga avviata l'attività successiva.
Per ulteriori informazioni sulle attività, vedere Parallelismo delle attività (runtime di concorrenza).
Vedere anche
Riferimenti
blocchi in lettura/scrittura (SRW)