共用方式為


比較同步處理資料結構與 Windows API

本主題會比較並行執行階段所提供的同步處理資料結構與 Windows API 所提供的同步處理資料結構在行為上的差異。

並行執行階段所提供的同步處理資料結構是遵循「合作式執行緒模型」(Cooperative Threading Model)。 在合作式執行緒模型中,同步處理原始型別會將自己的處理資源讓給其他執行緒。 這不同於「先佔式執行緒模型」(Preemptive Threading Model),在該模型中,處理資源是由控制端排程器或作業系統轉給其他執行緒。

critical_section

concurrency::critical_section 類別與 Windows CRITICAL_SECTION 結構類似,因為只有同處理序的執行緒才能使用它。 如需 Windows API 中之關鍵區段的詳細資訊,請參閱關鍵區段物件

reader_writer_lock

concurrency::reader_writer_lock 類別與 Windows 輕型讀取器/寫入器 (SRW) 鎖定類似。 下表說明相似和相異處。

功能

reader_writer_lock

SRW 鎖定

不可重新進入

可以將讀取器升階為寫入器 (升級支援)

沒有

沒有

可以將寫入器降階為讀取器 (降級支援)

沒有

沒有

寫入偏好設定鎖定

沒有

對寫入器的 FIFO 存取

沒有

如需 SRW 鎖定的詳細資訊,請參閱 Platform SDK 中的輕型讀取器/寫入器 (SRW) 鎖定

event

concurrency::event 類別與未命名的 Windows 手動重設事件類似。 不過,event 物件是以合作方式運作,而 Windows 事件則是以先佔方式運作。 如需 Windows 事件的詳細資訊,請參閱事件物件

範例

說明

若要更加了解 event 類別和 Windows 事件的差異,請參考下列範例。 這個範例會允許排程器最多建立兩個同時執行的工作,接著它會呼叫兩個類似的函式 (這兩個函式使用 event 類別和 Windows 手動重設事件)。 每個函式都會先建立數個工作,這些工作會等候某個共用事件變成已發出信號狀態。 每個函式接著會將資源讓給執行中的工作,然後發出事件的信號。 每個函式然後會等候所發出信號的事件。

程式碼

// 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();
}

註解

這個範例 (Example) 會產生下列範例 (Sample) 輸出:

  

因為 event 類別是以合作方式運作,所以排程器可以在有事件等候進入已發出信號狀態時,將處理資源重新配置給另一個內容。 因此,使用 event 類別的版本可以完成更多的工作。 在使用 Windows 事件的版本中,每個等候中的工作都必須先進入已發出信號狀態,下一個工作才會啟動。

如需工作的詳細資訊,請參閱 工作平行處理原則 (並行執行階段)

請參閱

參考

關鍵區段物件

輕型讀取器/寫入器鎖定 (SRW)

事件物件

概念

同步處理資料結構