关于C#中AutoResetEvent和ManualResetEvent的一点学习心得
来源:互联网 发布:apache有什么用 编辑:程序博客网 时间:2024/05/05 22:28
C#中的AutoResetEvent和ManualResetEvent用于实现线程同步。其基本工作原理是多个线程持有同一个XXXResetEvent,在这个XXXResetEvent未被set前,各线程都在WaitOne()除挂起;在这个XXXResetEvent被set后,所有被挂起的线程中有一个(AutoResetEvent的情况下)或全部(ManualResetEvent的情况下)恢复执行。
AutoResetEvent与ManualResetEvent的差别在于某个线程在WaitOne()被挂起后重新获得执行权时,是否自动reset这个事件(Event),前者是自动reset的,后者不是。所以从这个角度上也可以解释上段提到的“在这个XXXResetEvent被set后,所有被挂起的线程中有一个(AutoResetEvent的情况下)或全部(ManualResetEvent的情况下)恢复执行”——因为前者一旦被某个线程获取后,立即自动reset这个事件(Event),所以其他持有前者的线程之后WaitOne()时又被挂起;而后者被某个获取后,不会自动reset这个事件(Event),所以后续持有后者的线程在WaitOne()时不会被挂起。
set是让事件(Event)发生,而reset是让事件(Event)复位或者说忽略已经的事件(Event)。WaitOne是等待事件(Event)的发生,之后继续向下执行,否则一直等待。
在构造AutoResetEvent和ManualResetEvent的时候,它们的构造方法里需要一个参数initState,中文版MSDN(2005和2008)上的解释是“若要将初始状态设置为终止,则为 true;若要将初始状态设置为非终止,则为 false。”,我看了一个下午,没弄明白,而看一下英文版后大概就明白了“A value that you set to true to set the initial state of the specified event to signaled. Set this value to false to set the initial state of the event to nonsignaled.”(参见:http://msdn.microsoft.com/en-us/library/ee432364.aspx),大体意思是说这个参数决定是否在构造这个Event的时候就设置它为“发生”状态(signaled),如果是,则设置为true,也就是说持有这个Event的一个或多个线程在一开始就可以执行,而不需要挂起,至少是不会全部挂起(持有AutoResetEvent的一个或多个线程在任意时刻至多有一个线程在执行;持有ManualResetEvent的一个或多个线程会同时执行),否则为false(持有AutoResetEvent和ManualResetEvent的所有线程都将挂起,因为事件(Event)没有被set,即事件没有发生)。
另外稍微提一下,我在做多线程测试的时候,发现在线程数少的情况下,即使多个线程不做任何同步,如果对一个公共变量进行非互斥式修改时,不会至少很难出现不一致的情况,比如开100个线程,这个线程不做任何同步就分别给一个公共变量执行加1操作,那么结果在绝绝绝大部分的情况下是100!所以,我最后就下了狠心,把线程数增加到1000个,这个时候才出现问题,但问题也不是想象得那么严重——结果在991-1000之间!
再有,MSDN上对Monitor的Wait和Pulse两个方法用法的举例会导致死锁,一种死锁的执行顺序是:
1、线程tSecond在SecondThread()中执行到while(Monitor.Wait(m_smplQueue,1000))后,释放m_smplQueue的锁,线程tSecond挂起;
2、线程tFirst在FirstThread()中执行到Monitor.Wait(m_smplQueue)之前耗费的时间超过1000毫秒,此时线程tSecond退出,线程tFirst挂起,并且从此以后不会被恢复!
可以使用如下改动过的代码验证:
- 关于C#中AutoResetEvent和ManualResetEvent的一点学习心得
- C# 多线程 AutoResetEvent和ManualResetEvent
- c#中利用 AutoResetEvent和ManualResetEvent实现线程同步
- ManualResetEvent和AutoResetEvent的区别
- ManualResetEvent和AutoResetEvent的区别
- ManualResetEvent和AutoResetEvent的关系
- ManualResetEvent和AutoResetEvent的区别
- ManualResetEvent和AutoResetEvent的区别
- ManualResetEvent和AutoResetEvent的区别
- AutoResetEvent和ManualResetEvent的理解
- C#老生常谈之AutoResetEvent和ManualResetEvent
- C#多线程之二:ManualResetEvent和AutoResetEvent
- C#多线程之二:ManualResetEvent和AutoResetEvent
- C#多线程之二:ManualResetEvent和AutoResetEvent
- C#线程控制ManualResetEvent和AutoResetEvent
- C#多线程之ManualResetEvent和AutoResetEvent
- C#多线程之二:ManualResetEvent和AutoResetEvent
- C#多线程之二:ManualResetEvent和AutoResetEvent
- 驱动程序简单入门
- 重装Win 7修复ubuntu启动项
- 六个关键词!他们将影响未来20年网络
- SPI协议简介
- 桌面没有输入法的解决方案
- 关于C#中AutoResetEvent和ManualResetEvent的一点学习心得
- 要么java要么.net
- CppUnit在VS2010上的正确使用
- Hadoop
- 与其临渊羡鱼 不如退而结网
- ssacnf函数
- hdu3124——Moonmist
- 我的Linux之路
- 多媒体MCI的简单编程