C 如何使用OpenMP在多线程(超过10个线程)中打开文件

C 如何使用OpenMP在多线程(超过10个线程)中打开文件,c,openmp,C,Openmp,对不起,我英语不好 我正在尝试使用OpenMP以多线程方式加载图像文件。 但是,当我将线程数(num_threads())设置为10并执行该程序时,程序显示“Segmentation fault”。 如果我将线程数设置为9,它将工作。我的服务器(centos7.6)最多有32个可用线程和350GB内存。因此,我认为可以同时加载10个图像文件。 我不知道为什么会这样。在多线程中打开文件有任何限制吗? 这是我的示例代码 #include <stdio.h> #include <om

对不起,我英语不好

我正在尝试使用OpenMP以多线程方式加载图像文件。
但是,当我将线程数(num_threads())设置为10并执行该程序时,程序显示“Segmentation fault”。 如果我将线程数设置为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_线程(10)
而不是
num_线程
。 最后,将
target_文件
移动到节中更高效、更安全。 以下是生成的代码:

#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);
    }
}
#包括
#包括
int main()
{
int i=0;
omp_集合_嵌套(1);
printf(“最大可用线程数:%d\n”,omp_get_max_threads());
#用于num_线程的pragma omp并行(10)
对于(i=1;i<100;i++){
字符目标_文件[256]={0};
sprintf(目标文件“./data/%d.bmp”,i);
printf(“[%d]:目标文件:%s\n”,omp\u get\u thread\u num(),目标文件);
文件*fp;
fp=fopen(目标_文件,“rw”);
如果(fp==NULL){
printf(“无法打开文件:%s\n”,目标文件);
继续;
}
printf(“[%d]:%d.bmp文件已打开。\n”,omp\u get\u thread\u num(),i);
fclose(fp);
}
}

PS:请注意,您可以使用环境变量
OMP_NUM_THREADS
来调整运行时使用的线程数,而不是在代码中手动修复线程数(这更为灵活和可移植)。

即使文件未打开也会关闭,从而导致崩溃。 此外,应使用
num_线程(10)
而不是
num_线程
。 最后,将
target_文件
移动到节中更高效、更安全。 以下是生成的代码:

#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);
    }
}
#包括
#包括
int main()
{
int i=0;
omp_集合_嵌套(1);
printf(“最大可用线程数:%d\n”,omp_get_max_threads());
#用于num_线程的pragma omp并行(10)
对于(i=1;i<100;i++){
字符目标_文件[256]={0};
sprintf(目标文件“./data/%d.bmp”,i);
printf(“[%d]:目标文件:%s\n”,omp\u get\u thread\u num(),目标文件);
文件*fp;
fp=fopen(目标_文件,“rw”);
如果(fp==NULL){
printf(“无法打开文件:%s\n”,目标文件);
继续;
}
printf(“[%d]:%d.bmp文件已打开。\n”,omp\u get\u thread\u num(),i);
fclose(fp);
}
}

PS:请注意,您可以使用环境变量
OMP_NUM_THREADS
来调整运行时使用的线程数,而不是在代码中手动修复线程数(这更为灵活和可移植)。

在这里可能无关紧要,但您拼写错误了
\pragma
这是我键入时的错误,请考虑“目标文件”的范围…因此,我认为可以同时加载10个图像文件。如果您的处理是I/O绑定的,这不会使处理更快。如果文件都在同一个磁盘上,这实际上可能会使您的处理速度变慢,具体取决于您访问文件的方式。这里可能无关紧要,但您拼写错误了
#pragma
这是我键入时的错误,因此请考虑“target_file”的范围……因此,我认为可以同时加载10个图像文件。如果您的处理是I/O绑定的,这不会使处理更快。如果文件都在同一个磁盘上,实际上可能会使您的处理速度变慢,具体取决于您访问文件的方式。谢谢您的回答。我修复了它,但仍然不起作用。什么不起作用:你仍然有分割错误?您是否在不做任何修改的情况下执行此代码?您使用哪种编译器以及哪种版本?你的操作系统是什么?你的处理器是什么?很抱歉回复晚了。是的,我没有做任何修改就执行了。编译器是“gcc(gcc)4.8.5 20150623(Red Hat 4.8.5-36)”。操作系统是“CentOS Linux 7.6.1810版”。处理器是“英特尔(R)至强(R)CPU E5-2620 v4@2.10GHz”。您的GCC版本非常旧。我记得旧版本中有一些OpenMP错误,现在大部分在最新版本中得到修复,尽管我从未在如此简单的代码中看到编译器错误。你能试试最近的GCC(如GCC 9或GCC 10)吗?注意,有一些工具可以轻松地完成这项工作。我将GCC升级到9版并进行了尝试。它成功地工作了!谢谢你的建议。谢谢你的回答。我修复了它,但仍然不起作用。什么不起作用:你仍然有分割错误?您是否在不做任何修改的情况下执行此代码?您使用哪种编译器以及哪种版本?你的操作系统是什么?你的处理器是什么?很抱歉回复晚了。是的,我没有做任何修改就执行了。编译器是“gcc(gcc)4.8.5 20150623(Red Hat 4.8.5-36)”。操作系统是“CentOS Linux 7.6.1810版”。处理器是“英特尔(R)至强(R)CPU E5-2620 v4@2.10GHz”。您的GCC版本非常旧。我记得旧版本中有一些OpenMP错误,现在大部分在最新版本中得到修复,尽管我从未在如此简单的代码中看到编译器错误。你能试试最近的GCC(如GCC 9或GCC 10)吗?注意,有一些工具可以轻松地完成这项工作。我将GCC升级到9版并进行了尝试。它成功地工作了!谢谢你的建议。