共用方式為


比較同步處理資料結構與 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 事件的版本中,每個等候工作都必須進入訊號狀態,才能啟動下一個工作。

如需工作的詳細資訊,請參閱 工作平行處理原則

另請參閱

同步處理資料結構