我刚刚发现 gcc 的 OpenMP 实现(libgomp)没有调用 pthread_exit()。我需要它来使用 perfsuite(用于分析)。
有没有办法告诉 GCC 在将 OpenMP 代码转换为 pthread 代码时在 OpenMP 并行部分的末尾包含 pthread_exit() ?
我正在使用 GCC 4.7.0 和 Perfsuite 1.1.1 。
libgomp
实现线程池。一旦创建,池中的线程将保持空闲状态,直到它被通知成为线程组的成员。团队完成工作后,线程进入空闲循环,直到再次发出信号。池按需增长,但从不缩小。线程仅在程序完成时才发出退出信号。
您可以在此处libgomp
阅读 4.7.x 分支中实现线程池和团队的代码。
池线程是这样终止的:libgomp
注册一个名为 的析构函数team_destructor()
。每当main()
函数返回、exit(3)
被调用或libgomp
通过调用卸载库时都会调用它dlclose(3)
(如果之前使用 加载dlopen(3)
)。析构函数删除一个pthreads
名为 的键,该键具有由删除触发gomp_thread_destructor
的关联析构函数。使池中的所有线程作为它们的下一个任务执行。调用,因此池中的所有线程不再存在。gomp_free_thread()
gomp_free_thread()
gomp_free_pool_helper()
gomp_free_pool_helper()
pthread_exit(3)
这是一张漂亮的 ASCII 图片中的相同过程:
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)
请注意,这只在程序执行结束时发生一次,而不是在每个parallel
区域结束时发生。