使用相同值的多个消费者

时间:2016-10-31 19:44:02

标签: c# multithreading unity3d mono producer-consumer

我希望为某种生产者/消费者场景提供一些概念性的建议。

假设我有一个“生产者”线程,它通常以相当周期的方式创建一些整数或双精度值,但两者之间可能存在任意延迟。

现在有几个“消费者”线程,一旦值到达,所有人都应该开始并行处理这个值。

这些“消费者”线程中的每一个都可能需要另外的时间来完成其任务。一旦“消费者”准备就绪,它应该等待下一个产生的价值。

但是,如果使用之前的值完成任务花费的时间太长,则消费者应立即继续使用任何到期值(如果有)。我不需要队列,如果在消费者工作时有几个到达,则可以跳过值。因此,如果有新值,并且如果任何消费者已准备好消耗下一个值,那么这是最新的,这一点非常重要。

除了每个“消费者”有一个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);
        }
}

有生产者,每20ms创造一个新值。然后有两个消费者(可能会更晚)等待价值并用它做点什么。一个消费者需要10毫秒,另外30毫秒。 如果生产者/消费者同时开始,这应该导致以下时间表:

20      data = 20 => OnConsume1, OnConsume2 run with data = 20
30      OnConsume1 will wait for data, OnConsume2 is "working"
40      data = 40 => OnConsume1 run with data = 40, OnConsume2 still "working"
50      OnConsume1 will wait, OnConsume2 will run with data = 40
60      data = 60 => OnConsume1 run with data = 60, OnConsume2 is "working"
70      OnConsume1 will wait, OnConsume2 still "working"
80      data = 80 => OnConsume1 => data = 80, OnConsume2 should also run with 80 (neglecting the race that it might work with 60)

1 个答案:

答案 0 :(得分:0)

如果您想要一个具有最大深度的单个值,那么您会想要一个堆栈/队列。或者是一个可以为空的值,例如。

public int? value;

OnConsume1()
{
        while (running)
        {
                int myValue;
                if(value != null) // or value.HasValue
                {
                    myValue = value.Value; // or (int)value
                    value = null; // let other consumers know the value is being processed
                    // do something with data
                }
                Thread.Sleep(10);
        }
}

您希望使用C#的lock功能,只保留一个线程一次修改值。

如果您想使用线程安全容器Apache JMeter Properties Customization Guide