我是CPP的初学者,我们已经在类里面讨论了线程主题。
我正在尝试使用它,但它似乎无法按我的意愿工作。
我希望每个线程在 vector 中插入j的数量,然后将 vector 打印到控制台。
似乎所有这些对象都在循环结束后将j保留的最后一个值打印为“10”。
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]
),而不是引用。P.S.即使执行了此操作,也无法保证从0到9的所有值都将按顺序打印。这完全取决于以特定顺序执行
std::cout << ...
的线程,同样,您绝对不能保证哪个线程将与所有其他线程相关地到达该语句。关于c++ - 所有线程都做相同的事情。 cpp,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62365600/