2

我没有提供完整的列表,因为下面的代码对于那些熟悉破坏者的人来说已经足够了。问题是调用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);
    }
4

2 回答 2

4

我是disruptor-net的作者。

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

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

也就是说,.NET 并发队列比 Java 队列快得多,所以我建议使用 ConcurrentQueue 作为 disrutpor 或 BlockingCollection 的替代方案,它提供了非常接近 Disruptor 的语义。

于 2012-11-13T06:28:45.357 回答
1

在底层,Next()and的实现Publish()是基于Interlocked静态类的。所以确保代码被设计为线程安全的。它看起来是线程安全的,并且是一个整体。但它是线程安全的吗?我不知道。

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

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

于 2012-11-12T21:41:18.760 回答