Skip to content

[C#]WaitOne与AutoResetEvent

今天在写code时发现了原来代码里有一个AutoResetEvent,于是就研究了一下它的用法,这里做一下笔记。

AutoResetEvent根据我的理解,是做线程互斥时所使用的信号量,在有独占资源时使用,它提供了一对方法,WaitOne()与Set(),用以阻塞线程进入等待状态与发出信号让阻塞的线程放行,WaitOne()就像一个闸门,程序执行到这里会被阻塞,直到Set()方法被别的线程调用,发出信号,闸门打开,阻塞的线程才会继续执行,否则会一直等待下去。

这里使用了一个别人的例子,稍加修改,假设我现在要买书,买书分为三个步骤,决定要买的书(挑书),付钱,取书3步,由于我只有一个人,所以一次只能做一步,相当于独占资源,每做完一步,通知下个步骤进行,否则就处于阻塞状态。

我用3个线程来模拟,主线程选书,然后两个子线程模拟付钱和取书。代码如下:

class Program
{
	static AutoResetEvent buyEvent = new AutoResetEvent(false);//选书信号量
	static AutoResetEvent payEvent = new AutoResetEvent(false);//付钱信号量
	static AutoResetEvent getEvent = new AutoResetEvent(true);//取书信号量,注意为true,第一次直接放行
	const int bookCount = 10;//一共买10本书
	static int bookNum = 0;//当前第几本书
	static void Main(string[] args)
	{
		Thread payThread = new Thread(PayThread);//付钱线程
		Thread getThread = new Thread(GetThread);//取书线程
		payThread.Start();
		getThread.Start();
		for (int i = 1; i <= bookCount; i++) //开始选书
		{
			getEvent.WaitOne(); //等待取书完成
			bookNum = i;
			Console.WriteLine("Buy {0} book", bookNum); //选书
			buyEvent.Set(); //选书完成
		}

		//wait for the last getEvent return
		getEvent.WaitOne(); //等待最后一次取书完成,不然子线程还没跑完就被下面两个语句杀掉了
		payThread.Abort(); //付钱线程终止
		getThread.Abort(); //取书线程终止

		Console.Read();
	}

	static void PayThread()
	{
		while (true)
		{
			buyEvent.WaitOne(); //等待选书完成
			Console.WriteLine("Pay {0} book", bookNum); //付钱
			payEvent.Set(); //付钱完成
		}
	}

	static void GetThread()
	{
		while (true)
		{
			payEvent.WaitOne(); //等待付钱完成
			Console.WriteLine("Get {0} book", bookNum); //取书
			getEvent.Set(); //取书完成
		}
	}
}

代码里有两点需要注意的地方
1.在 getEvent 初始化时,我们把它设置为true,这是为了在第一次选书时能够顺利放行,因为第一次选书不需要等待取书完成。
2.在两个子进程结束之前,调用一次getEvent.WaitOne()这是确保最后一次取书能够执行完,不然子线程还没有处理完就被主线程杀掉了。

好了,这就是一个WaitOne和AutoResetEvent的简单应用,下面是一些参考链接:
http://blog.csdn.net/lanruoshui/article/details/5411270
http://msdn.microsoft.com/zh-cn/library/system.threading.autoresetevent.aspx

0 0 votes
Article Rating
Tags:
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x