65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.50/5 (3投票s)

2008 年 3 月 13 日

CPOL

2分钟阅读

viewsIcon

29290

downloadIcon

275

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 类和条件变量。

© . All rights reserved.