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();
        }
    }
 
}

运行结果:

1

posted @ 2017-09-01 10:17  耕耘理想的农夫  阅读(278)  评论(0编辑  收藏  举报