gpt4 book ai didi

C#生产者/消费者

转载 作者:IT王子 更新时间:2023-10-29 04:17:32 24 4
gpt4 key购买 nike

我最近遇到了生产者/消费者模式的 C# 实现。它非常简单(至少对我而言)非常优雅。

好像是2006年左右设计的,所以我想知道这个实现是不是
- 安全
- 仍然适用

代码如下(原代码引用http://bytes.com/topic/net/answers/575276-producer-consumer#post2251375)

using System;  
using System.Collections;
using System.Threading;

public class Test
{
static ProducerConsumer queue;

static void Main()
{
queue = new ProducerConsumer();
new Thread(new ThreadStart(ConsumerJob)).Start();

Random rng = new Random(0);
for (int i=0; i < 10; i++)
{
Console.WriteLine ("Producing {0}", i);
queue.Produce(i);
Thread.Sleep(rng.Next(1000));
}
}

static void ConsumerJob()
{
// Make sure we get a different random seed from the
// first thread
Random rng = new Random(1);
// We happen to know we've only got 10
// items to receive
for (int i=0; i < 10; i++)
{
object o = queue.Consume();
Console.WriteLine ("\t\t\t\tConsuming {0}", o);
Thread.Sleep(rng.Next(1000));
}
}
}

public class ProducerConsumer
{
readonly object listLock = new object();
Queue queue = new Queue();

public void Produce(object o)
{
lock (listLock)
{
queue.Enqueue(o);

// We always need to pulse, even if the queue wasn't
// empty before. Otherwise, if we add several items
// in quick succession, we may only pulse once, waking
// a single thread up, even if there are multiple threads
// waiting for items.
Monitor.Pulse(listLock);
}
}

public object Consume()
{
lock (listLock)
{
// If the queue is empty, wait for an item to be added
// Note that this is a while loop, as we may be pulsed
// but not wake up before another thread has come in and
// consumed the newly added object. In that case, we'll
// have to wait for another pulse.
while (queue.Count==0)
{
// This releases listLock, only reacquiring it
// after being woken up by a call to Pulse
Monitor.Wait(listLock);
}
return queue.Dequeue();
}
}
}

最佳答案

代码比那个更旧 - 我在 .NET 2.0 出现之前的某个时间写了它。生产者/消费者队列的概念比那个方式更古老:)

是的,据我所知,该代码是安全的 - 但它有一些缺陷:

  • 它不是通用的。现代版本肯定是通用的。
  • 它无法停止队列。停止队列(以便所有消费者线程退出)的一种简单方法是拥有一个可以放入队列的“停止工作” token 。然后,您可以添加与线程一样多的标记。或者,您有一个单独的标志来指示您要停止。 (这允许其他线程在完成队列中的所有当前工作之前停止。)
  • 如果作业非常小,一次处理一个作业可能不是最有效的做法。

老实说,代码背后的思想比代码本身更重要。

关于C#生产者/消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1656404/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com