微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有什么可以使静态布尔线程安全的吗?

如何解决有什么可以使静态布尔线程安全的吗?

我最近遇到了一些运行良好的代码,其中 static bool 在多个线程(单个写入器、多个接收器)之间共享,尽管没有同步。

类似的东西(简化):

//header A
struct A {
   static bool f;
   static bool isF() { return f; }
};

//Source A
bool A::f = false;

void threadWriter(){
    /* Do something */
    A::f = true;
}

// Source B
void threadReader(){
   while (!A::isF()) { /* Do something */}
}

对我来说,这种代码具有竞争条件,因为即使 bool 上的操作是原子的(在大多数 cpu 上),我们也不能保证来自编写器线程的写入对读取器线程可见。但有些人告诉我 f 是 static 的事实会有所帮助。

那么,C++11 中有什么东西可以使这段代码安全吗?或者任何与静态相关的东西会使这段代码工作?

解决方法

您的硬件可能能够在 bool 上自动运行。但是,这并不能使此代码安全。就 C++ 而言,您在不同线程中编写和读取 bool 没有同步,这是未定义的。

bool 设为静态不会改变这一点。

要以线程安全的方式访问 bool,您可以使用 std::atomic<bool>atomic 是使用互斥锁还是其他锁定取决于实现。

不过,如果每个 std::atomic<bool> 都访问相同的共享数据,threadReader() 也不足以同步 threadWriter()/*Do something */


但有些人告诉我,f 是静态的这一事实会有所帮助。

坦率地说,这听起来像货物崇拜。我可以想象这与静态局部变量的初始化是线程安全的事实相混淆。来自cppreference

如果多个线程尝试初始化同一个静态本地 变量并发,初始化只发生一次(类似 可以使用 std::call_once 获得任意函数的行为)。

注意:此功能的通常实现使用 双重检查锁定模式,可减少运行时开销 已初始化的本地静态为单个非原子布尔值 对比。

查找 Meyers singleton 以查看示例。虽然,这仅仅是关于初始化。例如这里:

 int& foo() {
     static int x = 42;
     return x;
 }

两个线程可以同时调用这个函数,x 只会被初始化一次。这对 x 本身的线程安全没有影响。如果两个线程调用 foo,一个写入,另一个读取 x,则存在数据竞争。但是,这是关于静态局部变量的初始化,与您的示例无关。我不知道他们告诉你 static 会“帮忙”是什么意思。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。