比較同步處理資料結構與 Windows API
本主題將並行執行時間所提供的同步處理資料結構行為與 Windows API 所提供的同步處理資料結構行為進行比較。
並行執行時間所提供的同步處理資料結構會遵循 合作式執行緒模型 。 在合作執行緒模型中,同步處理基本類型會明確地將其處理資源產生給其他執行緒。 這與 先占式執行緒模型 不同,其中處理資源會由控制排程器或作業系統傳輸至其他執行緒。
critical_section
concurrency::critical_section 類別類似于 Windows CRITICAL_SECTION
結構,因為它只能由一個進程的執行緒使用。 如需 Windows API 中重要區段的詳細資訊,請參閱 重要區段物件 。
reader_writer_lock
並行 ::reader_writer_lock 類別類似于 Windows 精簡讀取器/寫入器 (SRW) 鎖定。 下表說明相似之處和差異。
功能 | reader_writer_lock 類別 |
SRW 鎖定 |
---|---|---|
非重新進入 | Yes | Yes |
可以將讀取者升階為寫入器(升級支援) | No | No |
可以將寫入器降級給讀者(降級支援) | No | No |
寫入喜好設定鎖定 | 是 | No |
FIFO 存取寫入器 | 是 | No |
如需 SRW 鎖定的詳細資訊,請參閱 平臺 SDK 中的精簡讀取器/寫入器(SRW) 鎖定 。
event
concurrency::event 類別類似于未命名的 Windows 手動重設事件。 不過, event
物件會合作運作,而 Windows 事件會先占行為。 如需 Windows 事件的詳細資訊,請參閱 事件物件 。
範例
描述
若要進一步瞭解 類別和 Windows 事件之間的差異 event
,請考慮下列範例。 此範例可讓排程器最多建立兩個同時工作,然後呼叫兩個使用 類別和 Windows 手動重設事件的類似函 event
式。 每個函式會先建立數個工作,等候共用事件收到訊號。 接著,每個函式都會產生至執行中的工作,然後發出事件訊號。 然後,每個函式會等候訊號事件。
程式碼
// 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();
}
註解
此範例會產生下列範例輸出:
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.
因為類別 event
會合作運作,因此當事件等候進入訊號狀態時,排程器可以將處理資源重新配置至另一個內容。 因此,使用 類別的版本 event
會完成更多工作。 在使用 Windows 事件的版本中,每個等候工作都必須進入訊號狀態,才能啟動下一個工作。
如需工作的詳細資訊,請參閱 工作平行處理原則 。