使用AutoResetEvent信号实现生产者消费者队列

xiaoxiao2021-02-28  127

使用AutoResetEvent信号实现生产者消费者队列:

主程序作为生产者,添加工作任务;

工作者线程作为消费者,处理工作队列中的任务。

说明:

AutoResetEvent信号:使线程收到信号时,解除阻塞一次。

代码:

namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //使用using:在using作用域结束时调用ProducerConsumerQueue的析构方法dispose,释放资源 using (ProducerConsumerQueue _pcq = new ProducerConsumerQueue()) { _pcq.EnQueue("开始工作"); for (int i = 0; i < 10; i++) { _pcq.EnQueue("Work item:" + i); } _pcq.EnQueue("工作结束"); } //调用ProducerConsumerQueue的析构方法dispose,释放资源 } } class ProducerConsumerQueue : IDisposable { EventWaitHandle _ewh = new AutoResetEvent(false); Queue<string> _taskQueue = new Queue<string>(); Thread _work; readonly object _locker = new object();//加锁,实现队列的线程安全 public ProducerConsumerQueue() { _work = new Thread(Work); _work.Start();//启动工作者线程 } /// <summary> /// 任务入队列 /// </summary> /// <param name="task">任务</param> public void EnQueue(string task) { lock (_locker)//加锁,实现线程安全 { _taskQueue.Enqueue(task); } _ewh.Set();//信号AutoResetEvent:允许线程执行一次 } void Work() { while (true) { string task = null; if (_taskQueue.Count>0) { lock (_locker)//加锁,实现线程安全 { task = _taskQueue.Dequeue();//出队列 } if (task == null) return;//队列添加一条NULL的任务,表示任务执行完成,退出 } if (task != null) { Console.WriteLine("Performtask:" + task); Thread.Sleep(1000);//模拟任务执行 } else _ewh.WaitOne();//没有任务了,等待信号 } } public void Dispose() { EnQueue(null);//结束工作 _work.Join();//等待工作者线程结束 _ewh.Close();//释放等待句柄 } } }

转载请注明原文地址: https://www.6miu.com/read-17532.html

最新回复(0)