C ++线程错误

时间:2018-07-03 17:42:25

标签: c++ multithreading

我收到以下代码的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... 

1 个答案:

答案 0 :(得分:0)

问题:您正在为空线程调用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();
        }

现在您的代码在i = 0时崩溃,因为您在for循环的开头增加了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);