C++ 使用无锁指针队列在线程之间移动数据安全吗
我已经实现了一个简单的循环缓冲区,使用()C++ 使用无锁指针队列在线程之间移动数据安全吗,c++,multithreading,concurrency,C++,Multithreading,Concurrency,我已经实现了一个简单的循环缓冲区,使用()readerwriterqueue在线程之间移动数据,以防止(取消)应用程序中的分配。代码如下所示: using ElemPtr = std::unique_ptr<int>; moodycamel::ReaderWriterQueue<ElemPtr> emptyQueue(10); moodycamel::ReaderWriterQueue<ElemPtr> dataQueue(10); LoadQueueWith
readerwriterqueue
在线程之间移动数据,以防止(取消)应用程序中的分配。代码如下所示:
using ElemPtr = std::unique_ptr<int>;
moodycamel::ReaderWriterQueue<ElemPtr> emptyQueue(10);
moodycamel::ReaderWriterQueue<ElemPtr> dataQueue(10);
LoadQueueWithPointers(emptyQueue);
//If statements removed for brevity
auto producer = [&]() {
ElemPtr ptr;
while (true) {
emptyQueue.try_dequeue(ptr);
LoadData(ptr);
dataQueue.try_enqueue(std::move(ptr));
}
};
//If statements removed for brevity
auto consumer = [&]() {
ElemPtr ptr;
while (true) {
dataQueue.try_dequeue(ptr);
ProcessData(ptr);
emptyQueue.try_enqueue(std::move(ptr));
}
};
std::thread producerThread(producer);
std::thread consumerThread(consumer);
使用ElemPtr=std::unique\u ptr;
moodycamel::ReaderWriterQueue emptyQueue(10);
moodycamel::ReaderWriterQueue数据队列(10);
LoadQueueWithPointers(emptyQueue);
//为简洁起见,删除了If语句
汽车生产者=[&](){
elemptrptr;
while(true){
清空队列。尝试退出队列(ptr);
载荷数据(ptr);
dataQueue.try_enqueue(std::move(ptr));
}
};
//为简洁起见,删除了If语句
汽车消费者=[&](){
elemptrptr;
while(true){
数据队列。尝试退出队列(ptr);
过程数据(ptr);
emptyQueue.try_enqueue(std::move(ptr));
}
};
标准:螺纹生产商螺纹(生产商);
std::线程使用者读取(使用者);
在检查这段代码时,在我看来,如果使用者线程在RAM中更新数据(指针引用的数据)之前接收到指针,那么数据可能会损坏。我试图通过延迟、不同队列长度、不同数据大小以及将线程移动到物理上分离的处理器(套接字)来诱导数据损坏。到目前为止,我还没有发现数据损坏问题
因此,我的问题是:
moodycamel::ReaderWriterQueue
使用的内存围栏(std::memory\u order\u acquire
,std::memory\u order\u release
)是否也能保护我的(非原子)内存操作;DR:只要ReaderWriterQueue
的实现使用具有正确内存顺序的原子类型,就可以了
您需要的内存顺序是写入端的memory\u order\u release
,以及读取端的memory\u order\u acquire
。这些内存顺序意味着,原子写入之前的所有写入都需要首先发生,原子读取之后的所有读取都需要稍后发生。这些其他写/读操作包括访问ElemPtr
s后面的数据
由于队列本身需要将数据从一个线程发送到另一个线程,因此它需要在自己的原子元数据上使用完全相同的内存顺序,以便能够发送有效负载数据指针。因此,如果正确实现了
ReaderWriterQueue
,您应该是安全的。原子加载/存储的内存顺序存在,因为它们控制其他非原子加载/存储的重新排序方式。所以,据推测,你很好。但是,请注意,如果在强顺序CPU(如x86)上进行测试,那么CPU会隐藏许多潜在问题。因此,在另一个保证较弱的CPU(如ARM)上,您可能会遇到问题。