I wish to understand what do they mean here. Why would this program "hang"?
From https://bisqwit.iki.fi/story/howto/openmp/
OpenMP and
fork()
It is worth mentioning that using OpenMP in a program that callsfork()
requires special consideration. This problem only affects GCC; ICC is not affected. If your program intends to become a background process usingdaemonize()
or other similar means, you must not use the OpenMP features before the fork. After OpenMP features are utilized, a fork is only allowed if the child process does not use OpenMP features, or it does so as a completely new process (such as afterexec()
).This is an example of an erroneous program:
#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; }
When run, this program hangs, never reaching the line that outputs "b ended". There is currently no workaround as the libgomp API does not specify functions that can be used to prepare for a call to
fork()
.
The code as posted violates the POSIX standard.
The POSIX fork()
standard states:
A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the
exec
functions is called.
Running OMP-parallelized code is clearly violating the above restriction.