日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pthread_join和pthread_detach详解

發布時間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pthread_join和pthread_detach详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在任何一個時間點上,線程是可結合的(joinable)或者是分離的(detached)。一個可結合的線程能夠被其他線程收回其資源和殺死。在被其他線程回收之前,它的存儲器資源(例如棧)是不釋放的。相反,一個分離的線程是不能被其他線程回收或殺死的,它的存儲器資源在它終止時由 系統自動釋放。

??? 默認情況下,線程被創建成可結合的。為了避免存儲器泄漏,每個可結合線程都應該要么被顯示地回收,即調用pthread_join;要么通過調用pthread_detach函數被分離。

[cpp]
int pthread_join(pthread_t tid, void**thread_return);?
???????????????????????????????? 若成功則返回0,若出錯則為非零。?

int pthread_join(pthread_t tid, void**thread_return);
???????????????????????????????? 若成功則返回0,若出錯則為非零。??? 線程通過調用pthread_join函數等待其他線程終止。pthread_join函數分阻塞,直到線程tid終止,將線程例程返回的(void*)指針賦值為thread_return指向的位置,然后回收已終止線程占用的所有存儲器資源。[cpp] view plaincopyprint?int pthread_detach(pthread_t tid);?
???????????????????????????????? 若成功則返回0,若出錯則為非零。?

int pthread_detach(pthread_t tid);
???????????????????????????????? 若成功則返回0,若出錯則為非零。

??? pthread_detach用于分離可結合線程tid。線程能夠通過以pthread_self()為參數的pthread_detach調用來分離它們自己。
??? 如果一個可結合線程結束運行但沒有被join,則它的狀態類似于進程中的Zombie Process,即還有一部分資源沒有被回收,所以創建線程者應該調用pthread_join來等待線程運行結束,并可得到線程的退出代碼,回收其資源。

??? 由于調用pthread_join后,如果該線程沒有運行結束,調用者會被阻塞,在有些情況下我們并不希望如此。例如,在Web服務器中當主線程為每個新來的連接請求創建一個子線程進行處理的時候,主線程并不希望因為調用pthread_join而阻塞(因為還要繼續處理之后到來的連接請求),這時可以在子線程中加入代碼

??? pthread_detach(pthread_self())

或者父線程調用

??? pthread_detach(thread_id)(非阻塞,可立即返回)

這將該子線程的狀態設置為分離的(detached),如此一來,該線程運行結束后會自動釋放所有資源。


通過linux的pthread庫, 相信大家對創建/銷毀線程肯定很熟悉, 不過對pthread_join是否知道的更多呢?
先編寫一個常規的程序

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <pthread.h> #include <stdio.h> #include <string.h> void *thread_rountine(void * /*args*/) {   printf("thread %lu work\n", pthread_self()); } int main() {   pthread_t tid;   // *) 創建線程   pthread_create(&tid, NULL, thread_rountine, NULL);???   // *) 等待線程結束   pthread_join(tid, NULL);   return 0; }

  評注: 這是簡單的關于線程創建, 以及通過pthread_join阻塞等待子線程退出的例子

  pthread_join是否真的只是為了執行順序, 等待子線程退出的一種機制? 難道就沒有其他作用了嗎?
  答案是肯定的, 我們先來寫個程序, 做下對比:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <sys/time.h> #include <sys/resource.h> #include <pthread.h> #include <stdio.h> #include <string.h> void *thread_rountine(void * /*args*/) {   //pthread_detach(pthread_self());? ==> (2) } int main() {      rlimit rl;   getrlimit(RLIMIT_NPROC, &rl);   for ( int i = 0; i < rl.rlim_cur; i++ ) {     pthread_t tid;     int ret = pthread_create(&tid, NULL, thread_rountine, NULL);     if ( ret != 0 ) {       printf("error_msg => %s\n", strerror(ret));       break;     }     // pthread_join(tid, NULL);? ==> (1)   }   return 0; }

  評注: 這邊我們去掉了(1)pthread_join, (2) pthread_detach
  最終的程序輸出結果為:

1 error_msg => Resource temporarily unavailable

  我們可以大膽地猜想進程的線程數有個限制, 那我們的程序究竟在那個環節出錯了? 疏忽什么導致線程資源沒被完全收回?

  和Java開發多線程程序相比, 覺得搞java的人實在太幸福了.

  在回到原問題, 如果我們添加(1)pthread_join, 或者(2)pthread_detach, 問題解決了.
  我們查下man, 看看"專家"如何解說pthread_join

1 Failure to join with a thread that is joinable (i.e., one that is not detached), produces a "zombie thread". Avoid doing this, since each zombie thread consumes some system resources, and when enough zombie threads have accumulated, it will no longer be possible to create new threads (or processes).

  評注: 如果沒有對joinable的線程, 作pthread_join, 會導致線程成為"zombie thread", 依舊會占據這個資源. 這也就不難理解了,為何明明都是短任務線程, 沒有加pthread_join, 主線程就不能再創建線程了. pthread_join其實作了部分線程銷毀的工作. 另一方面, 子線程能通過pthread_detach函數, 在線程自身退出時做好清理工作.


總結

以上是生活随笔為你收集整理的pthread_join和pthread_detach详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。