【发布时间】:2017-12-16 14:55:10
【问题描述】:
std::uint64_t foo()
{
static std::uint64_t var = 0u;
std::lock_guard<std::mutex> lock(mutex);
std::uint64_t b;
do
{
b = bar();
}
while (b <= var);
var = b;
return b;
}
假设我们有两个线程。让第一个线程在调用 lock() 之前将变量 var 读取到寄存器,第二个线程在调用 lock() 之前将变量 var 读取到寄存器。然后第一个线程更改 var 但第二个线程看不到更改,因为它将值保留在寄存器中。这种非常糟糕的情况会发生吗?
我的意思是,通常只有局部变量会以这种方式进行优化:它们被放入寄存器,然后从那里读取,而不是从主内存中读取。据我了解,不应该以这种方式优化全局变量。但是静态局部变量呢?
【问题讨论】:
-
"...这种糟糕的情况会发生吗?..." - 是的。
std::mutex的同步效果是unlock()synchronizes-withlock()。但是您说的是在lock()之前使用对象 互斥锁提供的唯一保证是,lock()-unlock()序列中的线程 A 对bar的修改将是可见的到另一个线程,B 在 Block()s 互斥体之后。 -
您需要在使用之前锁定资源,否则其他线程可能会在分配和锁定之间锁定它,从而导致竞争条件
-
@WhiZTiM C++11 不保证线程安全的静态?
-
@BiagioFesta,确实如此... OP 的问题与
bar的初始化无关。这是关于在锁定互斥体之前使用bar
标签: c++ multithreading static local compiler-optimization