[英]C++ threads. Why always executes last thread?
为什么每次只执行最后一个线程? 我正在尝试将网格划分为 N 个工作人员,一半的网格始终不可触摸,而其他部分始终由 1 个最后创建的线程进行。 我应该使用数组而不是向量吗? 锁也无助于解决这个问题。
#include <iostream>
#include <unistd.h>
#include <vector>
#include <stdio.h>
#include <cstring>
#include <future>
#include <thread>
#include <pthread.h>
#include <mutex>
using namespace std;
std::mutex m;
int main(int argc, char * argv[]) {
int iterations = atoi(argv[1]), workers = atoi(argv[2]), x = atoi(argv[3]), y = atoi(argv[4]);
vector<vector<int> > grid( x , vector<int> (y, 0));
std::vector<thread> threads(workers);
int start, end, lastworker, nwork;
int chunkSize = y/workers;
for(int t = 0; t < workers; t++){
start = t * chunkSize;
end = start + chunkSize;
nwork = t;
lastworker = workers - 1;
if(lastworker == t){
end = y; nwork = workers - 1;
}
threads[nwork] = thread([&start, &end, &x, &grid, &t, &nwork, &threads] {
cout << " ENTER TO THREAD -> " << threads[nwork].get_id() << endl;
for (int i = start; i < end; ++i)
{
for (int j = 0; j < x; ++j)
{
grid[i][j] = t;
}
}
sleep(2);
});
cout << threads[nwork].get_id() << endl;
}
for(auto& th : threads){
th.join();
}
for (int i = 0; i < y; ++i)
{
for (int j = 0; j < x; ++j)
{
cout << grid[i][j];
}
cout << endl;
}
return(0);
}
[&start, &end, &x, &grid, &t, &nwork, &threads]
这条线是问题的根源。 您正在通过引用捕获所有变量,这不是您想要做的。
因此,每个线程都使用相同的变量,这也不是您想要的。
您应该只通过引用捕获grid
和threads
,其他变量应该按值捕获(“复制”到 lambda 中)
[start, end, x, &grid, t, nwork, &threads]
此外,您在任何地方都错误地访问grid
:将grid[i][j]
更改为grid[j][i]
thread([&start, &end, &x, &grid, &t, &nwork, &threads] {
=======
每个线程执行的 lambda 闭包捕获对nwork
的引用。
这意味着当for
循环迭代并启动每个线程时,每个捕获的线程将始终引用nwork
的当前值,在它这样做的时候。
因此,在所有线程实际初始化并实际进入 lambda 闭包之前,外循环可能很快完成创建每个线程 object,并且每个闭包看到相同的nwork
值,因为它是通过引用捕获的,这是最后一个线程 id。
您需要按值而不是按引用来捕获nwork
。
您传递的所有线程参数都是对线程 lambda 的引用。 但是,当循环在主线程中继续时,线程参数变量会发生变化,这也会改变它们在线程中的值,从而弄乱所有先前创建的线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.