我应该同步访问disruptor Next / Publish方法吗?

时间:2012-11-12 19:39:26

标签: c# disruptor-pattern

我没有提供完整列表,因为下面的代码对于那些熟悉破坏者的人来说已经足够了。 问题是调用NextPublish方法是否是线程安全的。在下面的例子中,什么是正确的?请注意,Attach可以同时从不同的线程调用。我有多个消费者。

例1。锁定一切:

    private object attachLock = new object();

    // can be called from parallel threads
    public void Attach(OrdersExecutor oe)
    {
        lock (attachLock)
        {
            long sequenceNo = ringBuffer.Next();
            ringBuffer[sequenceNo].Value = oe;
            ringBuffer.Publish(sequenceNo);
        }
    }

例2。锁定下一个:

    private object attachLock = new object();

    // can be called from parallel threads
    public void Attach(OrdersExecutor oe)
    {
        long sequenceNo;
        lock (attachLock)
        {
            sequenceNo = ringBuffer.Next();
        }
        ringBuffer[sequenceNo].Value = oe;
        ringBuffer.Publish(sequenceNo);
    }

示例3。没有锁

    private object attachLock = new object();

    // can be called from parallel threads
    public void Attach(OrdersExecutor oe)
    {
        long sequenceNo = ringBuffer.Next();
        ringBuffer[sequenceNo].Value = oe;
        ringBuffer.Publish(sequenceNo);
    }

2 个答案:

答案 0 :(得分:4)

我是disruptor-net的作者。

disruptor是一个并发集合,因此一旦配置正确,您不必应用任何锁定。在您的情况下,您应该使用MultiThreadedClaimStrategy初始化RingBuffer,因为您有多个生成器并使用示例3发布到环形缓冲区。

那就是说,我不鼓励在生产代码中使用disruptor-net,我暂时把它移植到我的业余时间并且没有在生产代码中使用它,它需要进一步测试。

也就是说,.NET并发队列明显快于Java队列,因此我建议使用ConcurrentQueue作为disrutpor的替代方法,或者使用BlockingCollection提供与Disruptor非常接近的语义。

答案 1 :(得分:1)

简而言之,Next()Publish()的实施基于Interlocked静态类。因此,确保代码设计是线程安全的。它看起来是线程安全的,并且像一个人一样。但它是否安全?我不知道。

这个项目似乎不太活跃,并且落后于Java API。有些测试失败(在Mono上),有些功能根本没有测试(WorkerPool)。小心使用。

我已经邮寄了作者邀请他发表评论,让我们等待他的澄清。