c - 如何使用 OpenMP 在多线程(超过 10 个线程)中打开文件
问题描述
对不起,我英语不好。
我正在尝试使用 OpenMP 在多线程中加载图像文件。
但是,当我将线程数(num_threads())设置为 10 并执行程序时,程序显示“分段错误”。如果我将线程数设置为 9,它将起作用。我的服务器(centos7.6)有 32 个最大可用线程和 350GB 内存。因此,我认为可以同时加载 10 个图像文件。
我不知道为什么会这样。在多线程中打开文件有任何限制吗?
这是我的示例代码。
#include <stdio.h>
#include <omp.h>
int main()
{
int i = 0;
char target_file[256] = { 0 };
omp_set_nested(1);
printf("maximum available threads : %d\n", omp_get_max_threads());
#pragma omp parallel for private(target_file) num_thread(10)
for (i = 1; i < 100; i++) {
sprintf(target_file, "./data/%d.bmp", i);
printf("[%d]:target file : %s\n", omp_get_thread_num(), target_file);
FILE *fp;
fp = fopen(target_file, "rw");
if (fp == NULL) {
printf("failed to open file : %s\n", target_file);
}
printf("[%d]: %d.bmp file opened.\n", omp_get_thread_num(), i);
fclose(fp);
}
}
这是我将 num_threads() 设置为 10 时的输出。
maximum available threads : 32
[8]:target file : ./data/81.bmp
[5]:target file : ./data/51.bmp
[0]:target file : ./data/1.bmp
[6]:target file : ./data/61.bmp
[0]: 1.bmp file opened.
[0]:target file : ./data/2.bmp
[6]: 61.bmp file opened.
[9]:target file : ./data/91.bmp
[3]:target file : ./data/31.bmp
[4]:target file : ./data/41.bmp
[8]: 81.bmp file opened.
[4]: 41.bmp file opened.
[4]:target file : ./data/42.bmp
[4]: 42.bmp file opened.
[0]: 2.bmp file opened.
[0]:target file : ./data/3.bmp
[0]: 3.bmp file opened.
[0]:target file : ./data/4.bmp
[0]: 4.bmp file opened.
[0]:target file : ./data/5.bmp
[0]: 5.bmp file opened.
[0]:target file : ./data/6.bmp
[0]: 6.bmp file opened.
[0]:target file : ./data/7.bmp
[0]: 7.bmp file opened.
[0]:target file : ./data/8.bmp
[0]: 8.bmp file opened.
[0]:target file : ./data/9.bmp
[0]: 9.bmp file opened.
[9]: 91.bmp file opened.
[8]:target file : ./data/82.bmp
[7]:target file : ./data/71.bmp
[5]: 51.bmp file opened.
[4]:target file : ./data/43.bmp
[4]: 43.bmp file opened.
[4]:target file : ./data/44.bmp
[4]: 44.bmp file opened.
[0]:target file : ./data/10.bmp
[0]: 10.bmp file opened.
[8]: 82.bmp file opened.
[5]:target file : ./data/52.bmp
[7]: 71.bmp file opened.
[1]:target file : ./data/11.bmp
[6]:target file : ./data/62.bmp
[3]: 31.bmp file opened.
[4]:target file : ./data/45.bmp
[4]: 45.bmp file opened.
[4]:target file : ./data/46.bmp
[4]: 46.bmp file opened.
[4]:target file : ./data/47.bmp
[4]: 47.bmp file opened.
[4]:target file : ./data/48.bmp
[4]: 48.bmp file opened.
[4]:target file : ./data/49.bmp
[8]:target file : ./data/83.bmp
[5]: 52.bmp file opened.
[7]:target file : ./data/72.bmp
[1]: 11.bmp file opened.
[6]: 62.bmp file opened.
[3]:target file : ./data/32.bmp
[2]:target file : ./data/21.bmp
[4]: 49.bmp file opened.
[8]: 83.bmp file opened.
[5]:target file : ./data/53.bmp
[7]: 72.bmp file opened.
[7]:target file : ./data/73.bmp
[7]: 73.bmp file opened.
[7]:target file : ./data/74.bmp
[7]: 74.bmp file opened.
Segmentation fault (core dumped)
解决方案
即使文件未打开导致崩溃,文件也会关闭。而且num_threads(10)
应该用代替num_thread
。最后,target_file
进入该部分更有效和安全。这是生成的代码:
#include <stdio.h>
#include <omp.h>
int main()
{
int i = 0;
omp_set_nested(1);
printf("maximum available threads : %d\n", omp_get_max_threads());
#pragma omp parallel for num_threads(10)
for (i = 1; i < 100; i++) {
char target_file[256] = { 0 };
sprintf(target_file, "./data/%d.bmp", i);
printf("[%d]:target file : %s\n", omp_get_thread_num(), target_file);
FILE *fp;
fp = fopen(target_file, "rw");
if (fp == NULL) {
printf("failed to open file : %s\n", target_file);
continue;
}
printf("[%d]: %d.bmp file opened.\n", omp_get_thread_num(), i);
fclose(fp);
}
}
PS:请注意,您可以使用环境变量OMP_NUM_THREADS
来调整运行时使用的线程数,而不是在代码中手动修复它(这更灵活和可移植)。
推荐阅读
- excel - VBA 运行时错误“380”:无法创建指定语言的脚本引擎
- android - 有没有办法使用android辅助功能api识别网页是否已完成加载内容?
- python - AWS lambda,未知服务:'quicksight'
- ruby-on-rails - 注销时在生产中使用设计的未初始化常量 UsersController
- html - 如何使用响应式设计将多个表单和标题分组放在同一行和中心?
- c# - 带有本地参考的 Lambda/Action
- bash - 如何在不调用 bash 的情况下从标准输入读取单个字符?
- python - 如何在 Matplotlib 中旋转花式箭头
- node.js - Node.js 没有给出任何响应并继续加载
- python - 如何访问 MibTableColumn 中的数据