c - OpenMP 段错误

标签 c char malloc openmp

我正在尝试将 OpenMP 并行化添加到工作代码中(仅添加到单个 for 循环),但是我无法消除段错误。问题出在这一行:

pos += sprintf(com + pos, "%d ", i);

com 是一个字符数组,我尝试将其定义为 char com[255]char *com = malloc(255*sizeof(char) ),在 for 循环内部和之前。当我在循环之前定义 com 时,我将 private(com) 添加到 #pragma omp parallel for 指令中。我还尝试初始化它并使用 firstprivate。 (pos 是一个整数,初始化为0)

当我不添加 -fopenmp 时,一切正常,但使用 -fopenmp 时会出现段错误。我错过了什么?

最佳答案

段错误来自于多个线程同时更新 pos 的值,因此将其设置为某个值,将 com + pos 转换为指向的指针超出或之前为 com 分配的内存。并行化此类循环的正确方法是连接私有(private)字符串中的值,然后以有序方式连接私有(private)字符串:

char com[255];
int pos = 0;

#pragma omp parallel
{
   char mycom[255];
   int mypos = 0;

   #pragma omp for schedule(static) nowait
   for (int i = 0; i < N; i++)
      mypos += sprintf(mycom + mypos, "%d ", i);

   // Concatenate the strings in an ordered fashion
   #pragma omp for schedule(static) ordered
   for (int i = 0; i < omp_get_num_threads(); i++)
   {
      #pragma omp ordered
      pos += sprintf(com + pos, "%s", mycom);
   }
}

有序结构可确保正确的同步,因此不需要关键。为了保证每个线程处理迭代空间的单个连续部分,schedule(static) 的使用非常重要。

关于c - OpenMP 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29247593/

相关文章:

c - 使用共享文件和 dup2() 将命令的标准输出通过管道传输到另一个命令的标准输入

c - 用函数修改 C 结构的子结构(用于 trie 的应用)

c - 在C中显示两个用户定义的数字之间的素数

c - 在 C 中使用 Malloc 添加两个数组 HW

c - 整页 Malloc

c - C中十进制到十六进制的转换

c++ - Windows 函数中的 char* 或 LPCWSTR

c++ - 为什么我不能在 struct 中初始化 char 数组

java - 转换字符(强制转换与 .getNumericValue)

c - realloc 如何增加内存块的大小?