gpt4 book ai didi

c++ - 使用无锁指针队列在线程之间移动数据是否安全

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:07:41 31 4
gpt4 key购买 nike

我已经实现了一个简单的循环缓冲区,使用 ( 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) 被 moodycamel::ReaderWriterQueue 使用也能保护我的(非原子)内存操作?

最佳答案

TL;DR:只要执行 ReaderWriterQueue<>使用具有正确内存顺序的原子类型,你没问题。

您需要的内存顺序是 memory_order_release在作者方面,memory_order_acquire在读者方面。这些内存顺序意味着,原子写入之前的所有写入都需要先发生,而原子读取之后的所有读取都需要稍后发生。这些其他写入/读取包括您对 ElemPtr 背后数据的访问

由于队列本身需要将数据从一个线程发送到另一个线程,因此它需要在其自己的原子元数据上使用完全相同的内存顺序,以便能够发送您的有效负载数据指针。因此,如果 ReaderWriterQueue<> 您应该是安全的正确实现。

关于c++ - 使用无锁指针队列在线程之间移动数据是否安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47095942/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com