linux中pthread_join()与pthread_detach()详解
前言:
1.linux線程執行和windows不同,pthread有兩種狀態joinable狀態和unjoinable狀態,如果線程是joinable狀態,當線程函數自己返回退出時或pthread_exit時都不會釋放線程所占用堆棧和線程描述符(總計8K多)。只有當你調用了pthread_join之后這些資源才會被釋放。若是unjoinable狀態的線程,這些資源在線程函數退出時或pthread_exit時自動會被釋放。
2.unjoinable屬性可以在pthread_create時指定,或在線程創建后在線程中pthread_detach自己, 如:pthread_detach(pthread_self()),將狀態改為unjoinable狀態,確保資源的釋放。或者將線程置為 joinable,然后適時調用pthread_join.
3.其實簡單的說就是在線程函數頭加上 pthread_detach(pthread_self())的話,線程狀態改變,在函數尾部直接 pthread_exit線程就會自動退出。省去了給線程擦屁股的麻煩。
eg:
?pthread_t tid;int status = pthread_create(&tid, NULL, ThreadFunc, NULL);if(status != 0){perror("pthread_create error");}pthread_detach(tid);一:pthread_join()
(1)pthread_join()即是子線程合入主線程,主線程阻塞等待子線程結束,然后回收子線程資源。
(2)函數說明
1)頭文件 : #include <pthread.h>
2)函數定義: int pthread_join(pthread_t thread, void **retval);
3)描述 :pthread_join()函數,以阻塞的方式等待thread指定的線程結束。當函數返回時,被等待線程的資源被收回。如果線程已經結束,那么該函數會立即返回。并且thread指定的線程必須是joinable的。
4)參數 :thread: 線程標識符,即線程ID,標識唯一線程。retval: 用戶定義的指針,用來存儲被等待線程的返回值。
5)返回值 : 0代表成功。 失敗,返回的則是錯誤號。
(3)實例
#include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h>void *thread_function(void *arg) {int i;for ( i=0; i<8; i++){printf("Thread working...! %d \n",i);sleep(1);}return NULL; }int main(void) {pthread_t mythread;if ( pthread_create( &mythread, NULL, thread_function, NULL) ){printf("error creating thread.");abort();}if ( pthread_join ( mythread, NULL ) ){printf("error join thread.");abort();}printf("thread done! \n");exit(0); }結果:
去掉pthread_join ( mythread, NULL )
#include <stdlib.h> #include <unistd.h> #include <stdio.h>void *thread_function(void *arg) {int i;for ( i=0; i<8; i++){printf("Thread working...! %d \n",i);sleep(1);}return NULL; }int main(void) {pthread_t mythread;if ( pthread_create( &mythread, NULL, thread_function, NULL) ){printf("error creating thread.");abort();} /*if ( pthread_join ( mythread, NULL ) ){printf("error join thread.");abort();} */printf("thread done! \n");exit(0); }結果:
二:pthread_detach()
(1)pthread_detach()即主線程與子線程分離,子線程結束后,資源自動回收。
(2)函數說明
1)函數原型:int pthread_detach(pthread_t tid);
2)功能:pthread_join()函數的替代函數,可回收創建時detachstate屬性設置為PTHREAD_CREATE_JOINABLE的線程的存儲空間。該函數不會阻塞父線程。pthread_join()函數用于只是應用程序在線程tid終止時回收其存儲空間。如果tid尚未終止,pthread_detach()不會終止該線程。當然pthread_detach(pthread_self())也是可以得
3)頭文件:#include <pthread.h> ? ? pthread非linux系統的默認庫, 需手動鏈接-線程庫 -lpthread
4)參數:tid:線程標識符
5)返回值:pthread_detach() 在調用成功完成之后返回零。其他任何返回值都表示出現了錯誤。如果檢測到以下任一情況,pthread_detach()將失敗并返回相應的值。
EINVAL:tid是分離線程
ESRCH:tid不是當前進程中有效的為分離線程
(3)實例
#include <stdlib.h> #include <unistd.h> #include <stdio.h> void print_message_function( void *ptr ); main ( ) {pthread_t thread1;pthread_create(&thread1,NULL,(void *)&print_message_function,(void *)0);int i;for(i=0;i<5;i++){printf("%d\n",thread1);}exit (0) ;} void print_message_function( void *ptr ) { pthread_detach(pthread_self());static int g;printf("%d\n", g++);pthread_exit(0) ;}結果:
//pthread_detach(pthread_self());
//使線成分離出來。當這個線程執行完成任務后釋放釋放資源。不然它會保留退出狀態,等待別人來取。
pthread_detach(threadid)和pthread_detach(pthread_self())沒有什么區別吧!有很嚴格的區別嗎???如果非要講區別不可,我覺得應該是調用他們的線程不同。
? ? ? pthread_detach(threadid)函數的功能是使線程ID為threadid的線程處于分離狀態,一旦線程處于分離狀態,該線程終止時底 層資源立即被回收;否則終止子線程的狀態會一直保存(占用系統資源)直到主線程調用pthread_join(threadid,NULL)獲取線程的退 出狀態。通常是主線程使用pthread_create()創建子線程以后,一般可以調用pthread_detach(threadid)分離剛剛創建的子線程,這里的threadid是指子線程的threadid;如此以來,該子線程止時底層資源立即被回收;被創建的子線程也可以自己分離自己,子線程調用pthread_detach(pthread_self())就是分離自己,因為pthread_self()這個函數返回的就是自己本身的線程ID;
總結
以上是生活随笔為你收集整理的linux中pthread_join()与pthread_detach()详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么事孤儿进程和僵死进程?
- 下一篇: linux下线程错误码表