【发布时间】:2020-02-12 19:12:12
【问题描述】:
我将我的问题分解为可重现的问题。在下面的代码中,我们有一个类printer。 printer::run 将打印 id_ 的 printer。 printer::spawn 会给你一个带有新打印机的线程。
在main 中,我正在生成 10 台打印机。创建的线程将在main 的末尾加入。我的期望是每次我们运行它时我们都会以某种顺序获得从 0 到 9 的数字(这是标题中的“确定性行为”)。不是这种情况。我们有时会得到其他数字。这是为什么?
#include <thread>
#include <iostream>
#include <vector>
class printer
{
public:
printer(int i) : i_(i){};
void run()
{
std::cout << i_ << '\n';
}
std::shared_ptr<std::thread> spawn()
{
return std::make_shared<std::thread>([=]() { run(); });
}
private:
int i_;
};
int main()
{
std::vector<std::shared_ptr<std::thread>> vec;
for (int i = 0; i < 10; ++i)
{
printer p{i};
vec.push_back(p.spawn());
}
for (auto a : vec)
{
a->join();
}
return 0;
}
关于我的期望的一些想法:
我猜我们在调用 spawn 时会复制当前 printer 的状态,因为我们通过值 (lambda) 而不是通过引用来捕获状态。
即使我们通过引用捕获,我们仍然将状态复制到新线程。
即使这没有发生,每个线程都有自己的printer。我错过了什么?
一些示例输出:
(为简洁起见,我将所有数字放在一行中)
1, 3, 4, 2, 5, 6, 7, 8, 9, -116618192
1513168144, 1513168144, 1513168144, 1513168144, 1513168144, 1513168144, 1513168144, 1513168144, 1513168144, 1513168144
1, 2, 33, , 6, 6, 7, 9, 9, 1344437296
1, 43, 2, 6, , 6, 7, 8, 9, -1194894256
有些输出没有全部 10 个数字...
【问题讨论】:
-
请在问题中包含实际输出。 “其他数字”表示不同的顺序或真正不同的数字,例如 42、314?
-
好的。我会这样做的。
-
如果你给我一个-1,你将不得不向我指出问题所在。请解释我在哪里愚蠢
-
“您必须向我指出问题所在”不,请参见此处:meta.stackexchange.com/a/325417/358287
-
是的,我知道这不是必需的。不过,答案仍然会有所帮助
标签: c++ multithreading pointers lambda member-functions