0

低レイテンシの C++ 同期キューが必要です。要件は次のとおりです。

  1. 実行時にメモリを割り当てません。新しいアイテムを memcpy したいだけです
  2. ロックフリー
  3. 一人の作家
  4. 複数のリーダー (並列)
  5. 並行読み書き

私はそれを自分で実装する必要がありますか、boostそれとも別の実装を共有できるものを使用できますか? メモリを割り当てたくないので、おそらくキューは内部でリングバッファを使用する必要があります。

以下は、私が書いたリングバッファですC#。4 を除くすべての要件を満たしています。C++ に書き直すのは簡単ですが、この実装で複数のリーダーをサポートし、ロックを解除する方法がわかりません。

public sealed class ArrayPool<T> where T : class, new()
{
    readonly T[] array;
    private readonly uint length;
    private readonly uint MASK;

    private volatile uint curWriteNum;
    private volatile uint curReadNum;

    public ArrayPool(uint length = 65536) // length must be power of 2
    {
        if (length <= 0) throw new ArgumentOutOfRangeException("length");
        array = new T[length];
        for (int i = 0; i < length; i++)
        {
            array[i] = new T();
        }
        this.length = length;
        MASK = length - 1;
    }

    public bool IsEmpty
    {
        get { return curReadNum == curWriteNum; }
    }

    /// <summary>
    /// TryGet() itself is not thread safe and should be called from one thread.
    /// However TryGet() and Obtain/Commit can be called from different threads
    /// </summary>
    /// <returns></returns>
    public T TryGet()
    {
        if (curReadNum == curWriteNum)
        {
            return null;
        }
        T result = array[curReadNum & MASK];
        curReadNum++;
        return result;
    }

    public T Obtain()
    {
        return array[curWriteNum & MASK];
    }

    public void Commit()
    {
        curWriteNum++;
        if (curWriteNum - curReadNum > length)
        {
            Log.Push(LogItemType.Error,
                "ArrayPool curWriteNum - curReadNum > length: "
                + curWriteNum + ' ' + curReadNum + ' ' + length);
        }
    }

}

使い方は簡単です。最初に を呼び出しObtain、次に項目を再構成してから を呼び出しますCommit

C#必要なものを示すためだけに実装を追加します。「複数のリーダー」のサポートを追加し、同時に実装をロックフリーに保つことは不可能だと思うので、何か新しいものが必要です。

4

0 に答える 0