【发布时间】:2022-01-12 20:35:23
【问题描述】:
我在 c++ 中使用多线程编写了这段代码,但我不确定为什么会得到我得到的输出。
void Fun(int* var) {
int myID;
myID = *var;
std::cout << "Thread ID: " << myID << std::endl;
}
int main()
{
using ThreadVector = std::vector<std::thread>;
ThreadVector tv;
std::cout << std::thread::hardware_concurrency() << std::endl;
for (int i = 0; i < 3 ; ++i)
{
auto th = std::thread(&Fun, &i);
tv.push_back(std::move(th));
}
for (auto& elem : tv)
{
elem.join();
}
}
我想知道 i 变量是否存在竞争条件,如果存在,它是如何交错的?我试图编译它,我不断得到线程 ID 打印输出为 3,但我很惊讶,因为我认为变量必须是全局的才能被各种新线程访问?
这就是我认为会发生的事情:线程 1 被创建,Fun 开始在线程 1 中运行,myid = 0,主线程继续运行并递增 i,创建第二个线程并且 myid 为 myid=1 ... 等等。因此打印输出将是 myID 以 i/e 1、2、3 为增量
我知道我可以用std::lock_guard 解决这个问题,但我只是想知道导致i 变量出现这种竞争条件的交错(加载、增量、存储)是如何发生的。
感谢您的帮助!
【问题讨论】:
-
myID = *var;和for循环中的++i之间存在竞争。 “Fun 开始在线程 1 中运行,myid = 0,主线程继续运行并递增 i” 没有理由认为它会按照这个顺序发生,这就是竞争条件。 -
为什么不考虑循环结束后所有线程启动的可能性?最坏的情况是
i的作用域完成,线程访问终止i。只需按值传递i,而不是其地址&i。 -
i的线程和范围之间不是也有竞争吗? -
Fun 开始在线程 1 中运行,myid = 0,主线程继续运行并递增 i,创建第二个线程并且 myid 为 myid=1... 等等on -- 单线程思维会导致多线程程序的消亡。
标签: c++ multithreading cpu