C#线程间通信:ManualResetEvent和AutoResetEvent
线程之间的通信是通过发信号来进行沟通的
ManualResetEvent:
1.ManualResetEvent,调用一次Set()允许继续全部阻塞线程,这是和AutoResetEvent的区别;
2.ManualResetEvent调用Set()后需要手动Reset(),将信号 设置为非终止状态,只有非终止状态线程中调用WaitOne()才能导所在的致线程阻止。
AutoResetEvent:
1.AutoResetEvent,调用一次Set()只能继续一个阻塞线程;
2.AutoResetEvent调用Set()后自动Reset()。
区别:
AutoResetEvent一次只能唤醒一个线程,其他线程还是堵塞,ManualResetEvent也就可以同时唤醒多个线程继续执行。
AutoResetEvent就像一个道门,收到Set信号后,门打开,通知一个线程进入,随后门又立即关闭。
AutoResetEvent被Set后自动调用Reset()重新阻塞,ManualResetEvent被Set后,需手动Reset()才会重新阻塞。
应用情况:
实际曝光过程中,坐台面+右台面。
左台面开始曝光:给从机发送数据 - 设置激光器电流 - 初始化将所有的AutoResetEvent设置为true - 开启曝光进程 - 曝光进程被阻塞 - 其他进程开始 - 预对位进程开启 - 检查平台四个角弯曲度 - CAM图形变换进程开启 - 激光器打开 - 能量自动标定进程开启 - 继续走曝光进程。
初始化将所有的AutoResetEvent设置为true:
m_LRCoop.SetAll();
public void SetAll() {
m_alignEvent.Set();
m_exposureEvent.Set();
m_feedInEvent.Set();
m_feedOutEvent.Set();
}
预对位进程开启:
lrCoop.AlignEvent.WaitOne();
引用:
引用一个博友的实例,比较形象:
用一个三国演义的典故来写段示例代码:http://www.cnblogs.com/charley_yang/archive/2010/10/31/1865663.html
话说曹操率领80W大军准备围剿刘备和孙权,面对敌众我寡的情况,诸葛亮与周瑜想到了一个妙计,用装满火药桶的大船去冲击曹操连在一起的战船,计划都安排好了,可谓“万事俱备 只欠东风”。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace Test { class Program { //默认信号为不发送状态 private static ManualResetEvent mre = new ManualResetEvent( false ); static void Main( string [] args) { EastWind wind = new EastWind(mre); //启动东风的线程 Thread thd = new Thread( new ThreadStart(wind.WindComming)); thd.Start(); mre.WaitOne(); //万事俱备只欠东风,事情卡在这里了,在东风来之前,诸葛亮没有进攻 //东风到了,可以进攻了 Console.WriteLine( "诸葛亮大吼:东风来了,可以进攻了,满载燃料的大船接着东风冲向曹操的战船" ); Console.ReadLine(); } } /// <summary> /// 传说中的东风 /// </summary> class EastWind { ManualResetEvent _mre; /// <summary> /// 构造函数 /// </summary> /// <param name="mre"></param> public EastWind(ManualResetEvent mre) { _mre = mre; } /// <summary> /// 风正在吹过来 /// </summary> public void WindComming() { Console.WriteLine( "东风正在吹过来" ); for ( int i = 0; i <= 5; i++) { Thread.Sleep(500); Console.WriteLine( "东风吹啊吹,越来越近了..." ); } Console.WriteLine( "东风终于到了" ); //通知诸葛亮东风已到,可以进攻了,通知阻塞的线程可以继续执行了 _mre.Set(); } } } |
运行结果: