.NET 封装 Vista/Server 2008 条件变量(新同步原语)






3.50/5 (3投票s)
Vista 引入了一个名为 CONDITION_VARIABLE 的新同步原语。在本文中,我将提供此原语的 .NET 封装(用 C++/CLI 编写)并解释其工作原理。
引言
随着 Windows Vista 的发布,Microsoft 引入了一个名为“条件变量”的新同步原语。在本文中,我将(拙劣地)解释条件变量的功能,并提供一个 .NET 封装。
背景
线程同步可能是一项复杂且有时令人沮丧的任务。我喜欢任何能让这项任务变得更轻松的事情。 Microsoft 就是这么做的,他们引入了条件变量。 当我看到它时,我说:“太棒了!迫不及待想使用它!”。 遗憾的是,该功能仅向非托管世界公开,而我工作于 C# 领域。 那么,该怎么办? 嗯…… 编写一个利用 C++/CLI 的封装器,将该功能公开给 .NET 世界,当然还要写一篇文章!
条件变量解释
那么,条件变量到底是什么? 条件变量允许线程在单个原子操作中释放锁(CRITICAL_SECTION
)并进入等待状态。 一旦线程被唤醒,它会立即需要先前释放的锁。 线程的唤醒通过 CONDITION_VARIABLE
和相关的 Win32 API 函数来控制。 有关更好的解释和 Win32 API 函数列表,请参阅 MSDN。
Using the Code
您将注意到的第一件事是,C++ 项目包含两个类,而不是一个。 鉴于 Microsoft 没有公开“关键节”功能(但是,它们通过 System.Threading.Monitor
方法提供了类似的功能),我也必须编写一个关键节的封装器,因为条件变量需要它们。
您还会注意到我将“条件变量”功能的封装类命名为“WaitCondition
”,它似乎更适合这种用法模式。 无论如何,您拥有代码,可以随意命名它。 在下面,您将找到使用这些类的基本模式(我包含了 Vista/Server 2008 SDK 的“使用条件变量”部分的一个示例应用程序的完整移植)
WaitCondition waitCondition = new WaitCondition();
CriticalSection criticalSection = new CriticalSection();
//Thread 1:
criticalSection.Enter();
//in a single atomic operation, release the critical section
//and sleep (waiting for the condition variable to be signaled
waitCondition.Sleep(criticalSection);
//Thread 2: wake up Thread 1
waitCondition.WakeOne();
//Thread 1: Once awake, do something....
DoSomething();
//Exit the Critical Section
criticalSection.Exit();
//Don't forget to dispose, or leverage the 'using' statement
//to ensure that the unmanaged CRITICAL_SECTION and
//CONDITION_VARIABLE structures are properly released
waitCondition.Dispose();
criticalSection.Dispose();
关注点
虽然从技术上讲,可以使用 CriticalSection
类代替 .NET 的 System.Threading.Monitor
类,但我建议不要这样做。 我针对 Monitor
类测试了这个类,它慢了大约 60%。 遗憾的是,没有办法利用 Monitor
类和条件变量。