【发布时间】:2016-10-31 19:44:01
【问题描述】:
我希望得到一些关于某种生产者/消费者场景的概念性建议。
假设我有一个“生产者”线程,它通常以相当周期性的方式创建一些整数或双精度值,但其间可能存在任意延迟。
现在有几个“消费者”线程,一旦值到达,所有线程都应该开始并行处理这个值。
这些“消费者”线程中的每一个都可能需要另外的时间来完成其任务。一旦“消费者”准备就绪,它就应该等待下一个产生的值。
但是,如果使用前一个值完成任务的时间过长,则消费者应立即继续使用任何到期的值(如果有)。我不需要队列,如果在消费者工作时有几个到达,则可能会跳过值。因此,唯一重要的是是否有新值,以及如果任何消费者准备好使用下一个值,那么哪个是最新的。
除了为每个“消费者”设置一个 AutoResetEvent/ManualResetEvent 之外,还有其他可行的方法吗?
具体方案应该是Unity3D,所以需要Mono2。
编辑:由于我对概念性建议感兴趣,因此很难提出一些源代码。我希望以下内容能稍微说明问题。
int data = 0;
producer = new Timer(20, OnTimer);
consumer1 = new Consumer(OnConsume1);
consumer2 = new Consumer(OnConsume2);
OnTimer()
{
data = data + 20;
TriggerConsumers();
}
OnConsume1()
{
while (running)
{
WaitForData();
// do something with data
Thread.Sleep(10);
}
}
OnConsume2()
{
while (running)
{
WaitForData();
// do something with data
Thread.Sleep(30);
}
}
有生产者,每 20 毫秒创建一个新值。然后有两个消费者(以后可能会更多)等待该值并对其进行处理。一个消费者需要 10 毫秒,另一个消费者需要 30 毫秒。 如果生产者/消费者同时开始,这应该会导致以下时间表:
20 数据 = 20 => OnConsume1,OnConsume2 运行数据 = 20 30 OnConsume1 将等待数据,OnConsume2 正在“工作” 40 数据 = 40 => OnConsume1 以数据 = 40 运行,OnConsume2 仍在“工作” 50 OnConsume1 将等待,OnConsume2 将运行 data = 40 60 数据 = 60 => OnConsume1 以数据 = 60 运行,OnConsume2 正在“工作” 70 OnConsume1 将等待,OnConsume2 仍在“工作” 80 data = 80 => OnConsume1 => data = 80,OnConsume2 也应该以 80 运行(忽略它可能与 60 一起工作的比赛)【问题讨论】:
-
没有一些代码(可能是伪代码),不清楚,至少对我来说,是什么问题。
-
当您从生产者那里收到以下数据时:2 然后 3。如果没有收到其他数据,是否应该先处理 3,然后处理 2?或者在这种情况下应该跳过 2 ?如果你们中的一个消费者的工作速度是另一个消费者的 2 倍,所以它可以同时处理 2 和 3,而另一个消费者只能处理 3。这种情况正常吗?
-
试图用一些伪代码来演示它。用例是游戏元素的时间线信息,每个消费者都需要知道“当前”时间。但是,我不想通过消费者同步循环,因为这会阻止其他人。因此,在您的示例中,如果 2 已被 3 覆盖,则永远不应处理它。一次只有一个值。但是如果已经处理了,没有新的,消费者就应该等待下一个。
-
是的,您需要基于 autoresetevent 实现自己的深度 = 1 的队列,如果存在,它将替换添加的项目,然后为每个消费者创建此队列的实例。在单独的线程中运行每个消费者。生产者应将新项目放入每个消费者队列中
-
另一种方式是使用观察者模式。在这种情况下,当收到新数据时,生产者必须在单独的线程中通知每个消费者
标签: c# multithreading unity3d mono producer-consumer