Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit onderwerp wordt het gedrag vergeleken van de synchronisatiegegevensstructuren die worden geleverd door de Gelijktijdigheidsruntime met die van de Windows-API.
De synchronisatiestructuren die worden geleverd door de Concurrency Runtime volgen het coöperatieve threading-model. In het coöperatieve threadingmodel leveren synchronisatieprimitieven expliciet hun verwerkingsbronnen op aan andere threads. Dit verschilt van het preemptive threading-model, waarbij verwerkingsbronnen worden overgebracht naar andere threads door de controleplanner of het besturingssysteem.
kritieke sectie
De concurrency::critical_section klasse lijkt op de Windows-structuurCRITICAL_SECTION, omdat deze alleen kan worden gebruikt door de threads van één proces. Zie Kritieke secties in de Windows-API voor meer informatie over kritieke secties.
lezer_schrijver_slot
De gelijktijdigheid::reader_writer_lock klasse lijkt op Windows slim reader/writer (SRW) vergrendelingen. In de volgende tabel worden de overeenkomsten en verschillen uitgelegd.
| Eigenschap |
reader_writer_lock klas |
SRW-vergrendeling |
|---|---|---|
| Niet-reentrant | Ja | Ja |
| Kan een lezer promoveren naar een schrijver (ondersteuning voor upgraden) | Nee. | Nee. |
| Kan een schrijver degraderen naar een lezer (downgrade-ondersteuning) | Nee. | Nee. |
| Schrijfvoorkeurvergrendeling | Ja | Nee. |
| FIFO-toegang tot schrijvers | Ja | Nee. |
Zie Slim Reader/Writer -vergrendelingen (SRW) in de Platform-SDK voor meer informatie over SRW-vergrendelingen.
gebeurtenis
De klasse concurrency::event lijkt op een niet-benoemde handmatig opnieuw in te stellen gebeurtenis in Windows. Echter, een event object werkt samen, terwijl een Windows-gebeurtenis zich preëmptief gedraagt. Zie Gebeurtenisobjecten voor meer informatie over Windows-gebeurtenissen.
Voorbeeld
Beschrijving
Bekijk het volgende voorbeeld om meer inzicht te krijgen in het verschil tussen de event klasse- en Windows-gebeurtenissen. In dit voorbeeld kan de planner maximaal twee gelijktijdige taken maken en vervolgens twee vergelijkbare functies aanroepen die gebruikmaken van de event klasse en een Windows-gebeurtenis voor handmatig opnieuw instellen. Elke functie maakt eerst verschillende taken die wachten tot een gedeelde gebeurtenis wordt gesignaleerd. Elke functie levert vervolgens de actieve taken op en geeft vervolgens de gebeurtenis aan. Elke functie wacht vervolgens op de gesignaleerde gebeurtenis.
Code
// 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();
}
Opmerkingen
In dit voorbeeld wordt de volgende voorbeelduitvoer geproduceerd:
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.
Omdat de event klasse zich coöperatief gedraagt, kan de planner verwerkingsbronnen opnieuw toewijzen aan een andere context wanneer een gebeurtenis wacht om de gesignaleerde status in te voeren. Daarom wordt er meer werk gerealiseerd door de versie die gebruikmaakt van de event klasse. In de versie die gebruikmaakt van Windows-gebeurtenissen, moet elke wachttaak de gesignaleerde status invoeren voordat de volgende taak wordt gestart.
Zie Taakparallellisme voor meer informatie over taken.