本主题将并发运行时提供的同步数据结构的行为与 Windows API 提供的同步数据结构的行为进行比较。
并发运行时提供的同步数据结构效仿协作式线程模型。在协作式线程模型中,同步基元将其处理资源显式让给其他线程。这不同于抢先式线程模型,在该模型中,处理资源由控制计划程序或操作系统传输给其他线程。
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 锁的更多信息,请参见平台 SDK 中的轻量级读取器/编写器 (SRW) 锁。
事件
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();
}
注释
此示例产生下面的示例输出:
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 事件的版本中,每个正在等待的任务必须进入终止状态,下一个任务才能开始。
有关任务的更多信息,请参见任务并行(并发运行时)。