【发布时间】:2018-07-03 17:42:25
【问题描述】:
我收到以下代码的 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...
【问题讨论】:
-
因为我们看不到这一行的输出
fprintf(stderr, "Joining threads... \n");可能是它没有进入这个块并加入线程吗?在这一行和外循环之后添加一个断点,看看哪个是第一个被命中的。 -
这读起来像 C,而不是 C++。为什么没有
std::string或std::vector<std::thread>? -
我检查了这一点,如果我注释掉了产生线程的部分,以及连接它们的部分,并且只运行逻辑以进入该代码块,它会打印错误消息。
-
未知数太多,无法提供体面的调试帮助。我怀疑你在
if (currentThread == MAX_THREADS || slice + MAX_SLICES_PER_THREAD > convertToVoxels(ARM_LENGTH))中有一个漏洞,它允许程序在不加入的情况下退出。例如,当您打印slice + MAX_SLICES_PER_THREAD >= convertToVoxels(ARM_LENGTH)的状态时,如果您只有slice + MAX_SLICES_PER_THREAD > convertToVoxels(ARM_LENGTH)),则在加入时。你可能会错过 equals 的情况。
标签: c++ multithreading