我剛剛發現gcc的OpenMP實現(libgomp)不調用pthread_exit()。 我需要使用perfsuite(用於剖析)。讓GCC在轉換OpenMP並行代碼時調用pthread_exit
有沒有什麼辦法可以告訴GCC在將OpenMP代碼轉換爲pthread代碼的同時,在OpenMP的並行部分的末尾包含pthread_exit()?
我使用的是GCC 4.7.0和Perfsuite 1.1.1。
我剛剛發現gcc的OpenMP實現(libgomp)不調用pthread_exit()。 我需要使用perfsuite(用於剖析)。讓GCC在轉換OpenMP並行代碼時調用pthread_exit
有沒有什麼辦法可以告訴GCC在將OpenMP代碼轉換爲pthread代碼的同時,在OpenMP的並行部分的末尾包含pthread_exit()?
我使用的是GCC 4.7.0和Perfsuite 1.1.1。
libgomp
實現線程池。創建完成後,池中的線程將保持空閒狀態,直到它成爲線程組的成員。團隊完成工作後,線程會進入空閒循環,直到再次發出信號。游泳池按需增長,但從不縮水。線程僅在程序結束時發出信號退出。
您可以閱讀在4.7.x分支here中實現線程池和團隊的libgomp
代碼。
池線程以這種方式終止: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
的結束。
嗨Hristo,謝謝你的回答。據我瞭解,當程序退出,即線程獲取信號時,它不會調用pthread_exit()。似乎我需要更改此文件(team.c)的代碼來執行此操作。是對的嗎?如果是這樣,有沒有簡單的方法來做到這一點? – Rakib
線程在'gomp_thread_start()'的後半部分運行循環,只要它們具有在對接屏障後執行的函數,否則它們將退出循環並簡單地返回。當線程調用'pthread_exit'時有一種情況,'libgomp'在運行時用'dlopen(3)'加載時就是這種情況。有一個關鍵的'gomp_thread_destructor'與一個關聯的析構函數'gomp_free_thread()'和一個名爲'team_destructor()'的文件析構函數被註冊。當你把庫關閉時,文件析構函數被調用,並且它使得所有的團隊線程都調用pthread_exit。 –
對不起,我的錯誤 - 函數'__attribute __((析構函數))'也在'main()'返回後調用。這意味着池線程肯定會到達他們稱之爲「pthread_exit」的地方,但不會在'main'函數返回之前。不幸的是,'libgomp' API對用戶不可用,並且您不能在'main()'結束之前調用池析構函數。 –