zoukankan      html  css  js  c++  java
  • 关于AutoResetEvent和ManualResetEvent

    两者都继承自EventWaitHandle,自然也就有点相通的地方了

    简单来说,无论是AutoResetEvent还是ManualResetEvent,都是通过发出Signal信号来通知正在等待的线程的。有人可能要问,为什么要用它们来做这些事情, 嗯, 是这样的, 在.Net的多线程环境中,资源的共享变得尤其重要,如果没有一个有效的方法来维护资源的原子状态,在抢占式的CPU环境中,所有的事情都会变得无法控制。AutoResetEvent和ManualResetEvent正是用来保证资源的原子性的一个手段的两个方面。正如它们的名字一样, AutoResetEvent会在每次被Signal了之后自动(Automatically)转变为UnSignal,而ManualResetEvent则不然,无论是Signal还是UnSignal都需要人为的介入去改变它的状态。

    在AutoResetEvent的构造函数中,有唯一的一个参数,initialState,Boolean类型,它用来初始化AutoResetEvent的Signal状态,True为Signal,False为UnSignal,这与ManualResetEvent的构造函数是一样的。

    AutoResetEvent或ManualResetEvent都是通过Set()/Reset()两个方法来Signal/UnSignal信号,通过调用WaitOne方法来阻塞当前线程,当收到Signal后就继续往下执行。上面提到过,AutoResetEvent会自动把信号复位(自动调用Reset),而ManualResetEvent则需要人手复位,也就是说,AutoResetEvent每次只允许一条线程进入,其它所有需要访问该资源的线程都要排队等候,直到AutoResetEvent得到信号后,下一条线程开始工作,同时AutoResetEvent又会自动复位信号,让其他线程继续等候;而ManualResetEvent则每次可以唤醒多个线程,因为当ManualResetEvent得到信号后,其他调用WaitOne方法的线程都将得到信号得以继续往下执行,ManualResetEvent不会自动复位信号,换句话说,除非手动的调用了ManualResetEvent.Reset方法,否则ManualResetEvent一直保持有信号状态,这样就可以同时唤醒多条线程了

    作为一个示例,下面的DemoCode一开始就运行一条子线程,然后用AutoResetEvent/ManualResetEvent来控制MessageBox的输出流程。

    如果在Foo和button1_Click里面用AutoResetEvent,一开始得到"1",然后每点击一次Button1得到"2"和"3"。

    如果用ManualResetEvent,一开始得到"1",然后只需点击Button1一次,就可以得到"2"和"3"了

    public partial class Form1 : Form
    {
        protected AutoResetEvent autoEvent;
        protected ManualResetEvent manualEvent;
        public Form1()
        {
            InitializeComponent();
            autoEvent = new AutoResetEvent(false);
            manualEvent = new ManualResetEvent(false);

            Thread aThread = new Thread(new ParameterizedThreadStart(Foo));
            aThread.Name = "aThread";
            aThread.IsBackground = true;
            aThread.Start();
        }

        private void Foo(object state)
        {
            MessageBox.Show("1");
            autoEvent.WaitOne();
            // manualEvent.WaitOne();
            MessageBox.Show("2");
            //manualEvent.Reset();
            autoEvent.WaitOne();
            //  manualEvent.WaitOne();
            MessageBox.Show("3");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            autoEvent.Set();
            // manualEvent.Set();
        }

    }

    魔兽就是毒瘤,大家千万不要玩。
  • 相关阅读:
    xps坐标计算
    xps文档
    xps坐标提取
    javascript
    python 类的继承
    PHP parse_url函数示例
    PHP 二维数组按照指定键排序(正序或倒叙均可)
    PHP substr()函数参数解释 通俗易懂
    PHP四大经典排序算法源码
    X友 NC 远程命令执行
  • 原文地址:https://www.cnblogs.com/tracy/p/1860523.html
Copyright © 2011-2022 走看看