gpt4 book ai didi

c++ - 我是否需要为线程之间的更改通知标志设置内存屏障?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:33:59 25 4
gpt4 key购买 nike

我需要一个非常快速的(在“读者的低成本”的意义上,而不是“低延迟”)线程之间的更改通知机制,以便更新读取缓存:

情况

Thread W (Writer) 仅偶尔更新数据结构 (S)(在我的例子中是 map 中的设置)。

Thread R (Reader) 维护着 S 的缓存并且非常频繁地读取它。当线程W更新S时,线程R需要在合理的时间内(10-100ms)收到更新通知。

架构为 ARM、x86 和 x86_64。我需要使用 gcc 4.6 及更高版本支持 C++03

代码

是这样的:

// variables shared between threads
bool updateAvailable;
SomeMutex dataMutex;
std::string myData;

// variables used only in Thread R
std::string myDataCache;

// Thread W
SomeMutex.Lock();
myData = "newData";
updateAvailable = true;
SomeMutex.Unlock();

// Thread R

if(updateAvailable)
{
SomeMutex.Lock();
myDataCache = myData;
updateAvailable = false;
SomeMutex.Unlock();
}

doSomethingWith(myDataCache);

我的问题

在 Thread R 中,“快速路径”(无可用更新)中没有发生锁定或障碍。这是一个错误吗?这种设计的后果是什么?

我是否需要将 updateAvailable 限定为 volatile

R 最终会得到更新吗?

目前我的理解

数据一致性是否安全?

这看起来有点像“双重检查锁定”。根据http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html内存屏障可用于在 C++ 中修复它。

然而,这里的主要区别在于共享资源永远不会在阅读器快速路径中被触及/读取。更新缓存时,一致性由互斥量保证。

R 会得到更新吗?

这就是它变得棘手的地方。据我了解,运行 Thread R 的 CPU 可以无限期地缓存 updateAvailable,有效地将 Read 方式移动到实际的 if 语句之前。

因此更新可能会持续到下一次缓存刷新,例如当另一个线程或进程被调度时。

最佳答案

使用 C++ 原子并生成 updateAvailable一个std::atomic<bool> .这样做的原因是,不仅仅是 CPU 可以看到变量的旧版本,尤其是编译器,它看不到另一个线程的副作用,因此从不费心重新获取变量,所以你永远看不到更新后的值在线程中。此外,通过这种方式,您可以获得有保证的原子读取,而如果您只是读取值,则不会。

除此之外,如果生产者仅在 updateAvailable 时才生产数据,您可能会摆脱锁定。是假的,你可以摆脱互斥锁,因为 std::atomic<>强制读取和写入的正确顺序。如果不是这种情况,您仍然需要锁。

关于c++ - 我是否需要为线程之间的更改通知标志设置内存屏障?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33956205/

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