2

ディスラプターに精通している人には以下のコードで十分なので、完全なリストは提供していません。Next問題は、メソッドの呼び出しPublishがスレッドセーフかどうかです。以下の例のうち、正しいものはどれでしょうか? 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の作者です。

ディスラプターは並行コレクションであるため、適切に構成した後はロックを適用する必要はありません。あなたの場合、複数のプロデューサーがあり、例 3 を使用してリング バッファーに発行するため、MultiThreadedClaimStrategy で RingBuffer を初期化する必要があります。

とは言っても、プロダクションコードでのdisruptor-netの使用はお勧めしません.しばらく前に空き時間に移植しましたが、プロダクションコードでは使用していません.さらにテストする必要があります.

そうは言っても、.NET 同時キューは Java キューよりも大幅に高速であるため、Disruptor の代わりに ConcurrentQueue を使用するか、ディスラプターに非常に近いセマンティックを提供する BlockingCollection を使用することをお勧めします。

于 2012-11-13T06:28:45.357 に答える
1

Next()内部的には、との実装は静的クラスPublish()に基づいています。Interlockedしたがって、コードがスレッドセーフになるように設計されていることを確認してください。それはスレッドセーフに見え、1 つのように震えます。しかし、それはスレッドセーフですか?知らない。

このプロジェクトはあまり活発ではないようで、Java API に遅れをとっています。一部のテストは (Mono で) 失敗し、一部の機能はまったくテストされません (WorkerPool)。注意して使用してください。

著者にコメントを求めるメールを送りました。彼の説明を待ちましょう。

于 2012-11-12T21:41:18.760 に答える