【发布时间】:2017-11-03 12:34:26
【问题描述】:
我已经实现了一个简单的循环缓冲区,以使用 (Camerons excellent) 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);
在检查此代码时,在我看来,如果消费者线程在数据(指针引用的)在 RAM 中更新之前接收到指针,则数据可能会损坏。我尝试使用延迟、不同的队列长度、不同的数据大小以及将线程移动到物理上独立的处理器(套接字)来诱导数据损坏。到目前为止,我还没有发现数据损坏问题。
因此我的问题是:到目前为止,我是否很幸运,并且存在等待发生的数据损坏问题或执行@使用的内存围栏(std::memory_order_acquire,std::memory_order_release) 987654326@ 还保护我的(非原子)内存操作?
【问题讨论】:
-
原子加载/存储的内存顺序存在,因为它们控制如何重新排序其他非原子加载/存储。所以,据说,你很好。但是请注意,如果您在强排序 CPU(如 x86)上对此进行测试,那么 CPU 会隐藏许多潜在问题。因此,在保证较弱的不同 CPU(如 ARM)上,您可能会遇到问题。
标签: c++ multithreading concurrency