将同步数据结构与 Windows API 进行比较

本主题将并发运行时提供的同步数据结构的行为与 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 事件的版本中,每个正在等待的任务必须进入终止状态,下一个任务才能开始。

有关任务的更多信息,请参见任务并行(并发运行时)

请参见

参考

临界区对象

轻量级读/写 (SRW) 锁

事件对象

概念

同步数据结构