天天看點

linux中pthread_join()與pthread_detach()詳解前言:一:pthread_join()

前言:

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);
}
           

結果:

linux中pthread_join()與pthread_detach()詳解前言:一:pthread_join()

去掉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);
}
           

結果:

linux中pthread_join()與pthread_detach()詳解前言:一:pthread_join()

二: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) ;
 }
           

結果:

linux中pthread_join()與pthread_detach()詳解前言:一:pthread_join()

//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;