线程同步之事件

简单介绍
AutoResetEvent和ManualResetEvent都派生自EventWaitHandle类(该类派生自WaitHandle)。EventWaitHandle构造时可以指定事件触发的方式(EventResetMode枚举),AutoResetEvent和ManualResetEvent只是构造时调用了EventWaitHandle的不同参数的构造方法,即
public  AutoResetEvent( bool  initialState) :  base (initialState, EventResetMode.AutoReset)
{
}

public  ManualResetEvent( bool  initialState) :  base (initialState, EventResetMode.ManualReset)
{
}
从而避免了构造时对具体类名的依赖。

基本用法
1. 定义事件。
2. 在一个线程中设置事件等待(WaitOne、WaitAll、WaitAny)。
3. 在另一个事件中Set事件,让等待线程继续。

简单例子
using  System;
using  System.Threading;

internal   class  Test
{
    
private   static  EventWaitHandle ewh  =   new  EventWaitHandle( false , EventResetMode.AutoReset);

    
public   static   void  Main()
    {
        Thread t1 
=   new  Thread(Thread1);
        t1.Start();

        Console.WriteLine(
" Start wait 1 " );
        ewh.WaitOne();
        Console.WriteLine(
" Go through 1 " );

        Console.WriteLine(
" Start wait 2 " );
        ewh.WaitOne();
        Console.WriteLine(
" Go through 2 " );
    }

    
public   static   void  Thread1()
    {
        Thread.Sleep(
1000 );

        Console.WriteLine(
" Event Set " );
        ewh.Set();
    }
}
如果是AutoResetHandle,那么Set完之后,ewh会重新置为“nonsignaled”的状态,如果要继续等待事件,就必须再次Set。
如果是ManualResetHandle,在Set完之后,状态不会自动重置,而是依然保留“signaled”的状态,那么不必再次Set就可以通过等待事件。可以通过Reset来重置事件到“nonsignaled”状态。

自动重置事件提供对资源的独占访问。如果没有线程等待时自动重置事件处于终止状态,则该事件一直保持终止状态,直到某个线程尝试在该事件上等待。该事件释放线程并立即重置,以阻止后面的线程。
手动重置事件类似于入口。当事件不处于终止状态时,在该事件上等待的线程将阻止。当事件处于终止状态时,所有等待的线程都被释放,而事件一直保持终止状态(即后面的等待不阻止),直到它的 Reset 方法被调用。如果一个线程必须完成一项活动后,其他线程才能继续,则手动重置事件很有用。

各种Wait的区别
WaitOne()以及各种重载,等待当前事件的Set,阻塞当前线程(或者一个指定的时间)。
WaitAll()以及各种重载,静态方法,等待事件数组中所有事件都得到Set。
WaitAny()以及各种重载,静态方法,等待事件数组中任一事件得到Set。

参考: http://www.rainsts.net/article.asp?id=170
http://msdn2.microsoft.com/zh-cn/library/system.threading.eventwaithandle.aspx

转载于:https://www.cnblogs.com/forck/archive/2008/04/16/1155684.html

猜你喜欢

转载自blog.csdn.net/weixin_33915554/article/details/93549671