C++ boost::lockfree:队列中的内存排序
考虑以下结构:C++ boost::lockfree:队列中的内存排序,c++,multithreading,boost,atomic,lock-free,C++,Multithreading,Boost,Atomic,Lock Free,考虑以下结构: struct T { ~T() { delete[] buff; } int* buff = nullptr; }; T* t = new T(); auto queue = boost::lockfree::queue<T*>(0); // Thread A t->buff = int[10]; queue.push(t); // Thread Z T* t = nullptr; while(true) if(queue.pop(t)) d
struct T {
~T() { delete[] buff; }
int* buff = nullptr; };
T* t = new T();
auto queue = boost::lockfree::queue<T*>(0);
// Thread A
t->buff = int[10];
queue.push(t);
// Thread Z
T* t = nullptr;
while(true)
if(queue.pop(t))
delete t; // Is this OK? If not, what kind of synchronization I need to make it OK?
struct{
~T(){delete[]buff;}
int*buff=nullptr;};
T*T=新的T();
自动队列=boost::无锁::队列(0);
//穿过
t->buff=int[10];
排队推送(t);
//螺纹Z
T*T=nullptr;
while(true)
if(queue.pop(t))
删除t;//这样行吗?如果没有,我需要什么样的同步才能使其正常?
一般的问题是不同的线程(A到Y)在共享指针(不是std::shared_ptr)上协同工作。在某个时刻,除了线程A之外,没有人使用指针
t
,线程A可以看到其他人对*t
所做的一切,因此线程A可以安全地调用delete t
。相反,它将t
推入队列,线程Z从队列中弹出,并执行删除t
。问题是我们如何确保线程Z看到最后一个分配给t->buff
的值?boost::lockfree::queue
中是否有任何同步可以保证这一点?或者我们需要自己做点什么?是的,这是安全的!您对从队列中弹出的值拥有唯一所有权push
必须使用memory\u order\u release
(或更强)和pop
必须使用memory\u order\u acquire
(或更强),因为否则实现将完全无用(您无法使用刚刚从队列中弹出的指针)。我没有检查代码,但是您说实现使用了内存\u顺序\u seq\u cst
,所以您应该很好 TL:DR:isqueue.push
是队列条目上的释放操作,而queue.pop(t)
是队列条目上的获取操作?我想是的,但是文档应该说。push
使用头部
,pop
使用尾部
。该实现甚至使用了std::memory\u order\u seq\u cst
。但我不认为这一定能保证我在寻找什么。@Koosha,为什么它不能保证你在寻找什么?SC CAS既是一个获取操作,也是一个释放操作,因此在线程Z中弹出后,对buff
的非原子写入是一个可见的副作用。