libgomp
implements thread pools. Once created, a thread in the pool remains idle until it is signalled to become member of a thread team. After the team finishes its work, the thread goes into an idle loop until it is signalled again. The pool grows on demand but never shrinks. Threads are only signalled to exit at program finish.
You can read the libgomp
code that implements thread pools and teams in the 4.7.x branch here.
Pool threads are terminated like this: libgomp
registers a destructor by the name of team_destructor()
. It is called whenever the main()
function returns, exit(3)
gets called or the libgomp
library is unloaded by a call to dlclose(3)
(if previously loaded with dlopen(3)
). The destructor deletes one pthreads
key by the name of gomp_thread_destructor
, which has an associated destructor function gomp_free_thread()
triggered by the deletion. gomp_free_thread()
makes all threads in the pool execute gomp_free_pool_helper()
as their next task. gomp_free_pool_helper()
calls pthread_exit(3)
and thus all threads in the pool cease to exist.
Here is the same process in a nice ASCII picture:
main() returns, exit() called or library unloaded
|
|
team_destructor() deletes gomp_thread_destructor
|
|
gomp_free_thread() called by pthreads on gomp_thread_destructor deletion
|
+-------------------------+---------------------------+
| | |
gomp_free_pool_helper() gomp_free_pool_helper() ... gomp_free_pool_helper()
installed as next task installed as next task installed as next task
| | |
| | |
pthread_exit(NULL) pthread_exit(NULL) ... pthread_exit(NULL)
Note that this only happens once at the end of the program execution and not at the end of each parallel
region.