gpt4 book ai didi

c++ - 如何在写入其他 std::atomic 之后强制读取 std::atomic?

转载 作者:行者123 更新时间:2023-11-30 02:34:03 26 4
gpt4 key购买 nike

我有两个线程,生产者和消费者。数据交换由 std::atomics 中的两个指针控制:

std::atomic<TNode*> next = nullptr;
std::atomic<TNode*> waiting = nullptr;

Thread Producer 发布准备好的数据,之后检查等待的值:

TNode* newNext = new TNode( );
// ... fill *newNext ...
next.store( newNext, std::memory_order_release );
TNode* oldWaiting = waiting.load( std::memory_order_seq_cst );
if( oldWaiting == nullptr )
{
/* wake up Consumer */
}

waiting 上的负载在 next 上的存储之后是至关重要的,但是 std::memory_order_seq_cst 有比我真正需要的更强大的保证,因为我真的只需要固定这两个访问的顺序。 是否可以在不需要 memory_order_seq_cst 的情况下获得我需要的内存顺序?

这是图片的其余部分:

线程消费者检查下一个。如果它发现它是空的,它会设置 waiting 以在阻塞自身之前向 Producer 发出信号。

TNode* newCurrent = next.load( std::memory_order_consume );
if( newCurrent == nullptr )
{
waiting.store( current, std::memory_order_relaxed );
/* wait, blocking, for next != nullptr */
}
current = newCurrent;

整个事情是一个生产者-消费者队列,它使锁定的需求保持在较低水平,而不需要所有复杂的机制。 next 实际上是在单向链表的当前节点内。数据通常是突发的,因此在大多数情况下,消费者会找到一大堆准备好消费的节点;除了极少数情况外,两个线程都只在突发之间经历一次锁定和阻塞/唤醒。

最佳答案

您实际上是在寻找 memory_order_release 的镜像顺序。即 memory_order_acquire

这比您要求的略强。在 .load 之后不能重新排序内存访问。但是,CPU 通常不提供对两次访问进行部分排序的方法,因此 C++ 也不具有这种粒度。

理论上 C++ 也有 release/consume 顺序,但没有人真正需要它。

关于c++ - 如何在写入其他 std::atomic 之后强制读取 std::atomic?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34896020/

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