修改过的生产者/消费者例子,有问题吗?

本文关键字:有问题 消费者 生产者 修改 | 更新日期: 2023-09-27 17:53:49

我修改了生产者/消费者的例子http://msdn.microsoft.com/en-us/library/yy12yx1f(v=vs.80).aspx。我不希望Consumer处理queue"事件"。相反,我使用无限循环(与生产者中使用的循环相同),并尝试尽快处理所有元素。这种方法有什么问题吗?如果我们可以使用无限循环,为什么在消费者和生产者之间需要"事件"?

    // Consumer.ThreadRun
    public void ThreadRun()
    {
        int count = 0;
        while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
        {
            lock (((ICollection)_queue).SyncRoot)
            {
                while (_queue.Count > 0)
                {
                    int item = _queue.Dequeue();
                    count++;
                }
            }
        }
        Console.WriteLine("Consumer Thread: consumed {0} items", count);
    }

修改过的生产者/消费者例子,有问题吗?

我看到了两个潜在的问题

  1. 当队列为空时,您的版本将处于繁忙的循环中,消耗宝贵的CPU,使用事件将线程置于睡眠状态,直到有实际工作要完成。通过锁定队列并在单个循环中处理队列中的所有元素,就像您正在做的那样,您否定了使用多个消费者线程处理队列的潜在好处。现在,因为在您的示例中您只增加一个计数,这可能看起来不是什么大问题,但是如果您开始对您退出队列的项目进行实际工作,您可以从多线程处理工作中受益。

如果你正在使用。net 4,你可能想看看使用BlockingCollection(T)类,它将提供一个更干净的解决方案,所有这些,更少的锁定启动

如果ExitThreadEvent的设置进入竞争状态(由于没有显示这部分代码,因此很难判断是否会发生这种情况),则可能会发生潜在的问题。

如果你能使用。net 4.0,你可以使用内置的BlockingCollection类来简单有效地解决这个问题。