Pet*_*ham 3 c++ multithreading
好的,所以我被告知这段代码不是线程安全的.
#include <iostream>
#include <thread>
static int sum[5];
static int get_sum()
{
int x=0;
for (int j=0;j<5;++j)
x += sum[j];
return x;
}
static void f1(int x){
sum[x] = 1;
std::cout << "f" <<x << ": " << sum[x] << " : " << get_sum() << std::endl;
}
int main() {
for (int j=0;j<5;++j)
sum[j] = 0;
std::thread t0(f1, 0);
std::thread t1(f1, 1);
std::thread t2(f1, 2);
std::thread t3(f1, 3);
std::thread t4(f1, 4);
while (get_sum() != 5) ;
t0.join();
t1.join();
t2.join();
t3.join();
t4.join();
std::cout << "final: " << get_sum() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释为什么该程序可能无法完成?我知道get_sum的运行值将是非确定性的,cout的输出将被随机交错,但这与程序完成无关.
Dav*_*rtz 12
可能无法在一个线程中访问值,而在另一个线程中可能会在另一个线程中修 这是规则.
我们可以推测特定平台上可能出现的特定问题.但一般来说,这是无益的,因为它会让人们认为,如果他们能够尽可能地修复每一种可能的方式,他们就会想到它可能会出错,那么他们的代码就可以了.但事实并非如此 - 事情可以而且确实会以你当时无法想到的方式出错.请不要这样想.由此类推理引起的失败列表很长,不需要再进行.
这是它失败的一种方式:编译器可能会get_sum在while循环之前将所有值内联并复制到寄存器中,从而导致循环永远重复.这是一个合法的优化,因为编译器可以看到您的代码可以在while循环期间的任何时间读取任何这些值,因此在该循环期间不允许其他线程修改它们.
现在,如果你阅读这个问题和答案,你会发现很多人都不会想到代码可能出错的方式.但是没关系,他们没有必要.存在这些规则是因为考虑代码可能出错的所有可能方式很困难,甚至不可能.因此,不要让你的代码的正确性依赖于你拥有超人类的能力.