我需要低延迟的 C++ 同步队列,要求是:
- 运行时没有内存分配,我只想memcpy新项目
- 无锁
- 一位作家
- 多个读卡器(并行)
- 并行读写
我应该自己实现它还是我可以使用来自boost
或可能你可以共享另一个实现的东西?因为我不想分配内存,所以队列很可能应该在里面使用 ring-buffer。
下面是我写的环形缓冲区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#
实现只是为了展示我需要什么。我认为不可能同时添加对“多个阅读器”的支持并保持实现无锁,所以我需要一些新的东西。