当我有一个std::condition_variable cond
和一些bool flag
时,我可以使用谓词等待它:
cond.wait_for(some_lock, std::chrono::milliseconds(100), { return flag; })
现在我想知道:从技术上讲,C ++只在C ++ 11中获得了一个合适的多线程内存模型,并且在多线程上下文中访问flag
变量基本上是未定义的。所以我应该声明它std::atomic<bool>
来逃避这种未定义的行为,对吗?
我特别想知道:如果我没有声明std::atomic
,那么我是否始终从flag
读取陈旧值,因为更新永远不会进入主内存?或者这是一个&#34;理论上是的情况,但实际上从未发生过&#34;?
答案 0 :(得分:5)
从技术上讲,C ++只在C ++ 11中获得了一个合适的多线程内存模型,并且在多线程上下文中访问flag变量基本上是未定义的。
只要没有数据争用,就可以很好地定义在C ++中访问线程共享变量。有关详细信息,请参阅Threads and data races:
...特别是,
std::mutex
的发布是与同步,因此,发生在之前由另一个线程获取相同的互斥锁,这使得可以使用互斥锁来防范数据争用。
互斥锁定/解锁构成获取/释放内存障碍。对于仅在互斥锁被锁定时访问的线程共享状态,您不需要std::atomic
。收到条件通知后,它首先锁定互斥锁,以便您可以安全地访问共享状态。
人们在尝试将std::atomic
变量与std::mutex/std::condition_variable
一起使用时会引入数据竞赛,并在不持有互斥锁的情况下访问std::atomic
。 An example