我想了解它们在这里的意思。为什么这个程序会“挂起”?
From https://bisqwit.iki.fi/story/howto/openmp/ https://bisqwit.iki.fi/story/howto/openmp/
OpenMP 和fork()
值得一提的是,在
调用的程序fork()
需要特别考虑。这
问题仅影响 GCC;国际刑事法院不受影响。如果你的程序
打算成为后台进程使用daemonize()
或其他
类似的意思是,您不得使用分叉之前的 OpenMP 功能。
使用 OpenMP 功能后,仅在以下情况下才允许分叉:
子进程不使用 OpenMP 功能,或者它作为
全新的流程(例如之后exec()
).
这是一个错误程序的示例:
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
void a(){
#pragma omp parallel num_threads(2)
{
puts("para_a"); // output twice
}
puts("a ended"); // output once
}
void b(){
#pragma omp parallel num_threads(2)
{
puts("para_b");
}
puts("b ended");
}
int main(){
a(); // Invokes OpenMP features (parent process)
int p = fork();
if(!p){
b(); // ERROR: Uses OpenMP again, but in child process
_exit(0);
}
wait(NULL);
return 0;
}
运行时,该程序挂起,永远不会到达输出“b
已结束”。目前没有解决方法,因为 libgomp API 没有
指定可用于准备调用的函数fork()
.
发布的代码违反了 POSIX 标准。
The POSIX fork()标准状态 http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html:
应使用单个线程创建进程。如果是多线程
进程调用 fork(),新进程应包含该进程的副本
调用线程及其整个地址空间,可能包括
互斥体和其他资源的状态。因此,为了避免
错误,子进程只能执行异步信号安全
操作,直到其中之一exec
函数被调用。
运行 OMP 并行化代码显然违反了上述限制。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)