繁体   English   中英

C++ 螺纹。 为什么总是执行最后一个线程?

[英]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]

这条线是问题的根源。 您正在通过引用捕获所有变量,这不是您想要做的。

因此,每个线程都使用相同的变量,这也不是您想要的。

您应该只通过引用捕获gridthreads ,其他变量应该按值捕获(“复制”到 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM