如下所述,这些都不是线程安全的,因为anyTrue
不是原子的,即使它可能在某些硬件上有原子性行为:
#include <thread>
bool blah() {
return true; // or false
}
int main()
{
bool anyTrue = false;
// I think foo should be thread safe:
auto foo = [&] {
if (blah()) {
anyTrue = true;
}
};
// but I'm not confident about bar:
auto bar = [&] {
anyTrue &= blah();
};
// parallel foo:
std::thread t1 (foo);
std::thread t2 (foo);
t1.join();
t2.join();
// parallel bar:
std::thread t3 (bar);
std::thread t4 (bar);
t3.join();
t4.join();
}
如果我anyTrue
atomic
,则不再编译,因为atomic
没有operator&=
:
#include <atomic>
#include <thread>
bool blah() {
return true; // or false
}
int main()
{
std::atomic< bool > anyTrue (false);
// I think foo should be thread safe:
auto foo = [&] {
if (blah()) {
anyTrue = true;
}
};
// but I'm not confident about bar:
auto bar = [&] {
anyTrue &= blah(); // error: no viable overloaded '&='
};
// parallel foo:
std::thread t1 (foo);
std::thread t2 (foo);
t1.join();
t2.join();
// parallel bar:
std::thread t3 (bar);
std::thread t4 (bar);
t3.join();
t4.join();
}
答案 0 :(得分:3)
这里根本没有线程安全:
std::rand
既不是重入也不是线程安全的。事实上,它保留了一个内部种子,所以你在这里深水。
&=
需要读取,修改,然后写入。那不是线程安全的。
赋值=
可能不是线程安全的(例如,两个线程可能同时写入同一个内存,结果未定义。)这是一个很好的老式数据种族。谁会说你的平台上没有真正的胖bool
?