本系列意在记录Windwos线程的相关知识点,包括线程基础、线程调度、线程同步、TLS、线程池等
本篇介绍与内核对象同步相关的Event对象和Mutex对象
AutoResetEvent和ManualResetEvent
同步事件有两种:AutoResetEvent和 ManualResetEvent。主要用户线程之间的通知,实现同步。无论是哪种,实际上是每个Event对象关联了一个事件内核对象。在【Windows】线程漫谈——线程同步之等待函数和事件内核对象中,详细介绍了事件内核对象和等待函数。.NET这里的两个版本是对它们的封装。下面简单回顾一下事件内核对象:
.NET的封装相应的有两个版本,自动重置和手动重置,他们实际上是一样的对象,只是行为稍有不同而已。在初始化事件对象的时候可以指定事件对象的初始化状态:static
AutoResetEvent myResetEvent =
new
AutoResetEvent(
false
);
//初始化为非触发状态
调用Set方法将事件对象置为触发状态:
event_1.Set();
调用Reset方法将事件对象置为非触发状态:
event_1.Reset();
调用WaitOne、WaitAny或WaitAll来使线程等待事件对象,它们的用法可以顾名思义。
下面对比一下.NET封装的事件对象和windows原生的事件对象,关于windows原生的事件内核对象参见【Windows】线程漫谈——线程同步之等待函数和事件内核对象
.NET | Windows API | 说明 |
AutoResetEvent | CreateEvent(bManualReset=false) | |
ManualResetEvent | CreateEvent(bManualReset=true) | |
.Set | SetEvent | |
.Reset | ResetEvent | |
AutoResetEvent | PulseEvent | .NET没提供PulseEvent,对于事件对象而言,用AutoResetEvent代替 |
-- | Named | .NET下事件对象似乎无法命名,也就是说事件对象不能跨进程。但是Windows原生的事件对象是跟其他内核对象一样是可以命名的,因此可以跨进程共享 |
EventWaitHandle.WaitOne | WaitForSingleObject | .NET通过在基类EventWaitHandle中定义Wait系列函数,封装了等待函数 |
EventWaitHandle.WaitAll | WaitForMultipleObjects (bWaitAll=true) | |
EventWaitHandle.WaitAny | WaitForMultipleObjects (bWaitAll=false) |
Mutex
.NET下单Mutex和Win32下单Mutex就是同一个东西,所以,完全可以从Win32的互斥量内核对象来理解。跟通常的内核对象一样,互斥量具有触发和未触发两种。当对象为触发状态的时候,等待他的线程将获得其访问权,并置为未触发状态;反之,对象为未触发状态时,等待他的线程将挂起。与Monitor和lock相同,Mutex也有记录所属线程ID,使用计数和递归计数,因此,同一个线程可以多次获得同一个Mutex的访问权限,但是要保证能够有相同次数的释放。
通过构造函数创建Mutex对象private
static
Mutex mut =
new
Mutex();
除了不带参数的构造函数,还有一些可选的参数用于创建Mutex对象:可以初始化创建的线程是否立刻拥有Mutex的访问权限、可以为Mutex命名,命名的Mutex可以对其他进程可见,而不仅仅是本进程的线程。关于命名MSDN还有如下的说明:
通过Mutex.Wait系列函数尝试获得对Mutex的访问权限
mut.WaitOne();
通过Mutex.ReleaseMutex释放Mutex
mut.ReleaseMutex();
在我之前的文章【Windows】线程漫谈——线程同步之信号量和互斥量中详细阐述了Win32下互斥量对象,下面对两种API作一个比较
.NET | Windows API | 说明 |
Mutex | CreateMutex | |
Mutex | OpenMutex | |
.ReleaseMutex | ReleaseMutex | |
Mutex(bool,string) | Named | .NET下可以对Mutex对象命名 |
EventWaitHandle.WaitOne | WaitForSingleObject | .NET通过在基类EventWaitHandle中定义Wait系列函数,封装了等待函数 |
EventWaitHandle.WaitAll | WaitForMultipleObjects (bWaitAll=true) | |
EventWaitHandle.WaitAny | WaitForMultipleObjects (bWaitAll=false) |
劳动果实,转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2012/08/19/event-and-mutex-in-net-thread-sync.html