C++ 线程错误 [英] C++ Threading Error

查看:95
本文介绍了C++ 线程错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am getting a C++ threading error with the below code:

    //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 个线程后加入所有现有线程,写入有问题的文件,然后重置并继续该过程,直到所有子问题都已完成.

The goal of this code is to create smaller sections of a large three dimensional array that can be threaded for increased processing speed, but can also be stitched back together when I write it to a file. To this end I tried to spawn n threads at a time, and after spawning the nth thread join all existing threads, write to the file in question, then reset things and continue the process until all sub problems have been completed.

我收到以下错误:

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)

在做了一些研究之后,问题似乎是我没有在它们超出范围之前加入我的线程.但是我认为我写的代码会正确地做到这一点.即本节:

After doing some research it seems that the issue is I am not joining my threads before they go out of scope. However I thought the code I wrote would do this correctly. Namely this section:

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

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

Could anyone point out my error (or errors) and explain it a little clearer so I do not repeat the same mistake?

注意我已经确认我正在进入内部 if 块,该块旨在加入线程.在注释掉线程生成行和线程连接行的情况下运行文件后,我得到以下输出:

Note I have verified I am getting into inner if block that is meant to join the threads. After running the file with the thread spawning line and thread joining line commented out I get the following output:

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... 

推荐答案

问题:您正在为空线程调用 join 方法 - 当您在不可连接的线程上调用 join 时,您不能这样做你会得到例外.

The issue: you are calling join method for empty thread - you cannot do this, when you call join on non-joinable thread you will get exception.

在这一行

thread threads[MAX_THREADS];

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

you created MAX_THREADS threads using its default constructor. Each thread object after calling default ctor is in non-joinable state. Before calling join you should invoke joinable method, if it returns true you can call join method.

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

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

Now your code crashes when i = 0 because you increment currentThread at the beginning of your for loop:

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

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

and you leave threads[0] with empty object while doing this assignment (before first assignment currentThread is 1)

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

这篇关于C++ 线程错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆