AutoResetEvent双向信号(生产者和消费者)例子
AutoResetEvent是一个非常有用的线程同步机制,尤其是在处理生产者和消费者问题的时候,尤其适用。本随笔记录下生产者和消费者一对一问题的两种写法并进行代码执行逻辑的分析,来加深对AutoResetEvent的理解。
写法一:
internal class Program { public static AutoResetEvent _product = new AutoResetEvent(false); public static AutoResetEvent _customer = new AutoResetEvent(false); static string _message = string.Empty; static void Main(string[] args) { Thread Product = new Thread(ProductItems); Thread Consume = new Thread(ConsumeItems); Product.Start(); Consume.Start(); Product.Join(); Consume.Join(); Console.WriteLine("finish"); Console.Read(); } static void ProductItems() { for (int i = 0; i < 5; i++) { _product.WaitOne(); _message = $"~:{i}"; Console.WriteLine("生产:" + _message); _customer.Set(); } } static void ConsumeItems() { for (int i = 0; i < 5; i++) { _product.Set(); _customer.WaitOne(); Console.WriteLine("消费:" + _message); } } }
执行结果:
写法二:
internal class Program { public static AutoResetEvent _product = new AutoResetEvent(false); public static AutoResetEvent _customer = new AutoResetEvent(true); static string _message = string.Empty; static void Main(string[] args) { Thread Product = new Thread(ProductItems); Thread Consume = new Thread(ConsumeItems); Product.Start(); Consume.Start(); Product.Join(); Consume.Join(); Console.WriteLine("finish"); Console.Read(); } static void ProductItems() { for (int i = 0; i < 5; i++) { _customer.WaitOne(); _message = $"~:{i}"; Console.WriteLine("生产1:" + _message); _product.Set(); } } static void ConsumeItems() { for (int i = 0; i < 5; i++) { _product.WaitOne(); Console.WriteLine("消费1:" + _message); _customer.Set(); } } }
运行结果:
要点:
其一:AutoResetEvent(true)和AutoResetEvent(false);两者的区别是前者初始化时就有一个票据,相当于在运行AutoResetEvent(false)后,直接调用了set方法。
其二:程序要继续往下运行的条件为:1.必须有票据。2.必须在等待(当然如果没有等待就无所谓生产者和消费者协调问题了,不在本文范围内),两者的顺序可以有先有后,无所谓谁前谁后。
其三:等待句柄对操作系统的负载并不高。