首页 > 解决方案 > 如何使用 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)

标签: copenmp

解决方案


即使文件未打开导致崩溃,文件也会关闭。而且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来调整运行时使用的线程数,而不是在代码中手动修复它(这更灵活和可移植)。


推荐阅读