我是 CPP 的初学者,我们在类里面已经讨论了线程的主题。 我正在尝试使用它,但它似乎没有按照我想要的方式工作。
我希望每个线程将 j 的数量插入 vector 内,然后将 vector 打印到控制台。
看起来它们都打印了值“10”,这是循环结束后 j 保存的最后一个值。
vector<int> foo(int x) {
vector<int> a;
a.push_back(x);
return a;
}
void print(vector<int> vec) {
for (int i = 0; i<int(vec.size()); i++)
cout << vec[i] <<endl;
}
void foo2(int x) {
vector<int> b;
thread thr([&] {b = foo(x); });
thr.join();
mtx1.lock();
print(b);
mtx1.unlock();
}
int main() {
vector<thread> th;
for (int j = 0; j < 10; j++)
th.emplace_back(([&] {foo2(j); }));
for (int j = 0; j < 10; j++)
th[j].join();
}
注意:我希望线程 vector 将进入函数内部,调用一个新线程,该线程会将数字插入 vector ,然后打印。
我得到的输出是:
10
10
10
10
10
10
10
10
10
10
我的目标是:
0
1
2
3
4
5
6
7
8
9
感谢您的帮助。
最佳答案
for (int j = 0; j < 10; j++)
th.emplace_back(([&] {foo2(j); }));
lambda 捕获 j
通过引用(毕竟,这就是 [&]
的意思),lambda 被用来构造一个新的 std::thread
,还有这个for
立即循环迭代,递增 j
.
但是,如果您仔细观察,您会注意到 j
是通过引用捕获的,并且 C++ 无法保证新线程将读取 j
的值。 ,并调用foo2()
,在 for
之前父线程中的循环迭代并递增j
.
这里发生的情况是,for 循环运行得足够快,因此它在所有线程实际开始自行运行之前完成,并且它们看到的只是 j
的最后一个值。 (甚至还不是这样,因为当这个 j
循环终止时,这个特定的 for
超出范围并被销毁,因为它被声明为 for
循环的本地,这在技术上意味着访问 j
makes demons fly out of your nose ) .
解决方案:捕获j
按值(即 [=]
或 [j]
),而不是引用。
附注即使这样做之后,您也无法保证从 0 到 9 的所有值都会按顺序打印。这完全取决于执行 std::cout << ...
的线程按照特定的顺序,同样,您绝对不能保证哪个线程将到达与所有其他线程相关的该语句。
关于c++ - 所有线程都做同样的事情。程序文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62365600/