首页 > 解决方案 > C++ 线程错误

问题描述

我收到以下代码的 C++ 线程错误:

    //create MAX_THREADS arrays for writing data to
thread threads[MAX_THREADS];
char ** data = new char*[MAX_THREADS];
char * currentSlice;
int currentThread = 0;
for (int slice = 0; slice < convertToVoxels(ARM_LENGTH); slice+=MAX_SLICES_PER_THREAD){
    currentThread++;
    fprintf(stderr, "Generating volume for slice %d to %d on thread %d...\n", slice, slice + MAX_SLICES_PER_THREAD >= convertToVoxels(ARM_LENGTH) ? convertToVoxels(ARM_LENGTH) : slice + MAX_SLICES_PER_THREAD, currentThread);

    try {
        //Allocate memory for the slice
        currentSlice = new char[convertToVoxels(ARM_RADIUS) * convertToVoxels(ARM_RADIUS) * MAX_SLICES_PER_THREAD]; 
    } catch (std::bad_alloc&) {
        cout << endl << "Bad alloc" << endl;
        exit(0);
    }
    data[currentThread] = currentSlice;

    //Spawn a thread
    threads[currentThread] = thread(buildDensityModel, slice * MAX_SLICES_PER_THREAD, currentSlice);

    //If the number of threads is maxed out or if we are on the last thread
    if (currentThread == MAX_THREADS || slice + MAX_SLICES_PER_THREAD > convertToVoxels(ARM_LENGTH)){ 
        fprintf(stderr, "Joining threads... \n");

        //Join all threads
        for (int i = 0; i < MAX_THREADS; i++){
            threads[i].join();
        }

        fprintf(stderr, "Writing file chunks... \n");

        FILE* fd = fopen("density.raw", "ab");
        for (int i = 0; i < currentThread; i++){
            fwrite(&data[i], sizeof(char), convertToVoxels(ARM_RADIUS) * convertToVoxels(ARM_RADIUS), fd);
            delete data[i];
        }
        fclose(fd);
        currentThread = 0;
    }
}

此代码的目标是创建大型三维数组的较小部分,这些部分可以线程化以提​​高处理速度,但也可以在我将其写入文件时缝合在一起。为此,我尝试一次生成 n 个线程,并在生成第 n 个线程后加入所有现有线程,写入有问题的文件,然后重置并继续该过程,直到完成所有子问题。

我收到以下错误:

Generating volume for slice 0 to 230 on thread 1...
Generating volume for slice 230 to 460 on thread 2...
Generating volume for slice 460 to 690 on thread 3...
Generating volume for slice 690 to 920 on thread 4...
Generating volume for slice 920 to 1150 on thread 5...
Generating volume for slice 1150 to 1380 on thread 6...
Generating volume for slice 1380 to 1610 on thread 7...
terminate called without an active exception
Aborted (core dumped)

在做了一些研究之后,问题似乎是我没有在它们超出范围之前加入我的线程。但是我认为我编写的代码会正确执行此操作。即本节:

//Join all threads
for (int i = 0; i < MAX_THREADS; i++){
    threads[i].join();
}

谁能指出我的错误(或错误)并解释得更清楚一点,这样我就不会重复同样的错误?

编辑:注意我已经验证我正在进入用于连接线程的内部 if 块。在运行带有线程生成行和线程连接行注释掉的文件后,我得到以下输出:

Generating volume for slice 0 to 230 on thread 1...
Generating volume for slice 230 to 460 on thread 2...
Generating volume for slice 460 to 690 on thread 3...
Generating volume for slice 690 to 920 on thread 4...
Generating volume for slice 920 to 1150 on thread 5...
Generating volume for slice 1150 to 1380 on thread 6...
Generating volume for slice 1380 to 1610 on thread 7...
Joining threads and writing file chunk... 

标签: c++multithreading

解决方案


问题:您正在join为空线程调用方法 - 您不能这样做,当您在不可加入的线程上调用 join 时,您将得到异常。

在这一行

thread threads[MAX_THREADS];

您使用其默认构造函数创建了 MAX_THREADS 个线程。调用默认 ctor 后的每个线程对象都处于不可连接状态。在调用之前join你应该调用joinable方法,如果它返回true你可以调用join方法。

        for (int i = 0; i < MAX_THREADS; i++){
           if(threads[i].joinable())
              threads[i].join();
        }

现在您的代码崩溃了,因为您在 for 循环开始时i = 0递增:currentThread

for (int slice = 0; slice < convertToVoxels(ARM_LENGTH); slice+=MAX_SLICES_PER_THREAD){
  currentThread++; // <---

并且您在执行此分配时留下threads[0]空对象(在第一个分配currentThread为 1 之前)

    threads[currentThread] = thread(buildDensityModel, slice * MAX_SLICES_PER_THREAD, currentSlice);

推荐阅读