C#线程学习(一) AutoResetEvent与ManualResetEvent

来源:互联网 发布:php websocket教程 编辑:程序博客网 时间:2024/05/18 19:23

最近因为工作原因涉及到多线程编程,学到的心得在这里记录下来与大家分享,如有不正确的地方欢迎指出。

AutoResetEventManualResetEvent是C#中线程通信使用的两种信号量,他们都通过调用WaitOne函数来等待信号,通过调用Set来释放其他等待中的线程,通过调用Reset来重新阻止其他线程。

他们的构造函数相似,均接受一个bool类型参数,指示初始状态。

public AutoResetEvent (bool initialState)

public ManualResetEvent(bool initialState)

当构造参数为true时信号为终止状态,允许一个或多个等待线程继续;当构造参数为false时信号为非终止状态,导致线程阻止

AutoResetEvent与ManualResetEvent的区别在于,AutoResetEvent的Set信号被另一线程接收后,其会自动重置为阻止状态,而ManualResetEvent并不会自动重置,他将保持非阻止状态。即AutoResetEvent一次只能唤醒一个线程,而ManualResetEvent一次将唤醒所有等待的线程。

下面我们用这样一个例子来说明两者的区别,在下面的程序中,thread1和thread2均等待同一个信号量resetEvent。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace ThreadDemo{    class Program    {        static AutoResetEvent resetEvent;                static void thread_call()        {            string name = Thread.CurrentThread.Name;            resetEvent.WaitOne();            Console.Out.WriteLine("Thread {0} is called.", name);        }        static void Main(string[] args)        {            resetEvent = new AutoResetEvent(false);            Thread thread1 = new Thread(thread_call);            thread1.Name = "Thread_1";            Thread thread2 = new Thread(thread_call);            thread2.Name = "Thread_2";            thread1.Start();            thread2.Start();            Thread.Sleep(2000);            Console.Out.WriteLine("Set 1st");            resetEvent.Set();            Thread.Sleep(2000);            Console.Out.WriteLine("Set 2nd");            resetEvent.Set();            Console.ReadKey();        }    }}

两个子线程启动后均在等待resetEvent,故均阻塞在WaitOne处。

两秒后主线程第一次调用Set,此时thread2被唤起,由于resetEvent是AutoResetEvent,故其自动重置,thread1不会被唤起。

主线程第二次调用Set,此时thread1被唤起。

输出如下:

Set 1stThread Thread_1 is called.Set 2ndThread Thread_2 is called.
若将以上程序中的AutoResetEvent换为ManualResetEvent,主线程第一次调用Set时,两线程均被唤起。

输出如下:

Set 1stThread Thread_1 is called.Thread Thread_2 is called.Set 2nd



原创粉丝点击