三肄渗、linux中pthread_join()與pthread_detach()解析

關(guān)于線程用法可以參考這些文章
一搞乏、Linux中 C/C++線程使用

二扶欣、Pthread 鎖與 C++讀寫鎖

三仗考、linux中pthread_join()與pthread_detach()解析

四音同、linux中pthread_cond_wait()與pthread_cond_signal ()解析

Note: 關(guān)于內(nèi)核使用線程方法可以參考之前寫的另外一篇文章

內(nèi)核線程(kthread)的簡單使用

這篇文章主要是介紹 pthread兩種狀態(tài): joinable狀態(tài)和unjoinable狀態(tài)

  1. linux線程執(zhí)行 pthread有兩種狀態(tài)joinable狀態(tài)和unjoinable狀態(tài)
    默認是joinable 狀態(tài),可以通過這個api 來獲取其狀態(tài) pthread_attr_getdetachstate
    另外可以通過如下代碼來設(shè)置為狀態(tài)joinable 還是 unjoinable
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&thr, &attr, &thread_start, NULL);

更多細節(jié)可以看 pthread_create , pthread_attr_init

還有一種方法是線程創(chuàng)建后在線程中調(diào)用 pthread_detach, 如:pthread_detach(pthread_self())秃嗜,將狀態(tài)改為unjoinable狀態(tài)权均,確保資源的釋放。

void  ThreadFunc( void *ptr )
{       
        pthread_detach(pthread_self());
        pthread_exit(0) ;
}

 pthread_t tid;
 int status = pthread_create(&tid, NULL, ThreadFunc, NULL);
 if(status != 0)
 {
     perror("pthread_create error");
 }

或者外部主線程主動調(diào)用 pthread_detach(tid)

 pthread_t tid;
 int status = pthread_create(&tid, NULL, ThreadFunc, NULL);
 if(status != 0)
 {
     perror("pthread_create error");
 }
 pthread_detach(tid);
  1. 如果線程是joinable狀態(tài)锅锨,當線程函數(shù)自己返回退出時或pthread_exit時都不會釋放線程所占用堆棧和線程描述符(總計8K多)叽赊。只有當你調(diào)用了pthread_join之后這些資源才會被釋放。
  2. 若是unjoinable狀態(tài)的線程必搞,堆棧和線程描述符這些資源在線程函數(shù)退出時或pthread_exit時自動會被釋放必指。

總的來說就是在線程屬性設(shè)置為unjoinable,在函數(shù)尾部直接 pthread_exit線程就會自動退出恕洲,省去了給線程主動調(diào)用pthread_join 回收資源的麻煩塔橡。

Demo 1:使用默認狀態(tài)

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
void *thread_function(void *arg)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        printf("%s:Thread working...! %d \n", __FUNCTION__, 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("%s:Thread done! \n", __FUNCTION__);
    exit(0);
}

打印輸出:

main:Thread done!

因為主線程main 跑的比子線程快,子線程中 thread_function 的打印是不是打印出來的

Demo 2:使用pthread_join 阻塞主線程

(1)pthread_join()即是子線程合入主線程研侣,主線程阻塞等待子線程結(jié)束谱邪,然后回收子線程資源。
(2)函數(shù)說明
1)頭文件 : #include <pthread.h>
2)函數(shù)定義: int pthread_join(pthread_t thread, void **retval);
3)描述 :pthread_join()函數(shù)庶诡,以阻塞的方式等待thread指定的線程結(jié)束。當函數(shù)返回時咆课,被等待線程的資源被收回末誓。如果線程已經(jīng)結(jié)束扯俱,那么該函數(shù)會立即返回。并且thread指定的線程必須是joinable的喇澡。
4)參數(shù) :thread: 線程標識符迅栅,即線程ID,標識唯一線程晴玖。retval: 用戶定義的指針读存,用來存儲被等待線程的返回值。
5)返回值 : 0代表成功呕屎。 失敗让簿,返回的則是錯誤號购撼。
將上述Demo 1 中的注釋放開笑窜,可以看到 子線程中 thread_function 的打印

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
void *thread_function(void *arg)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        printf("%s:Thread working...! %d \n", __FUNCTION__, 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("%s:Thread done! \n", __FUNCTION__);
    exit(0);
}

打印輸出

thread_function:Thread working...! 0
thread_function:Thread working...! 1
thread_function:Thread working...! 2
thread_function:Thread working...! 3
thread_function:Thread working...! 4
thread_function:Thread working...! 5
thread_function:Thread working...! 6
thread_function:Thread working...! 7
main:Thread done!

Demo 3:使用pthread_detach()

(1)pthread_detach()即主線程與子線程分離,子線程結(jié)束后憔狞,資源自動回收蹂安。
(2)函數(shù)說明
1)函數(shù)原型:int pthread_detach(pthread_t tid);
2)功能:pthread_join()函數(shù)的替代函數(shù)椭迎,可回收創(chuàng)建時detachstate屬性設(shè)置為PTHREAD_CREATE_JOINABLE的線程的存儲空間。該函數(shù)不會阻塞父線程田盈。pthread_join()函數(shù)用于只是應(yīng)用程序在線程tid終止時回收其存儲空間畜号。如果tid尚未終止,pthread_detach()不會終止該線程允瞧。當然pthread_detach(pthread_self())也是可以得
3)頭文件:#include <pthread.h> pthread非linux系統(tǒng)的默認庫弄兜, 需手動鏈接-線程庫 -lpthread
4)參數(shù):tid:線程標識符
5)返回值:pthread_detach() 在調(diào)用成功完成之后返回零。其他任何返回值都表示出現(xiàn)了錯誤瓷式。如果檢測到以下任一情況替饿,pthread_detach()將失敗并返回相應(yīng)的值。
EINVAL:tid是分離線程
ESRCH:tid不是當前進程中有效的為分離線程

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
void *thread_function(void *arg)
{
    pthread_detach(pthread_self());
    int i;
    for (i = 0; i < 8; i++)
    {
        printf("%s:Thread working...%d \n", __FUNCTION__, i);
        sleep(1);
    }
    pthread_exit(NULL);
}

int main(void)
{
    pthread_t mythread;

    if (pthread_create(&mythread, NULL, thread_function, NULL))
    {
        printf("error creating thread.");
        abort();
    }
    sleep(5);
    printf("%s: tid:%lu\n", __FUNCTION__, mythread);
    printf("%s: Thread work done! \n", __FUNCTION__);
    exit(0);
}

打印輸出

thread_function:Thread working...0
thread_function:Thread working...1
thread_function:Thread working...2
thread_function:Thread working...3
thread_function:Thread working...4
main: tid:1
main: Thread work done!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贸典,一起剝皮案震驚了整個濱河市视卢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廊驼,老刑警劉巖据过,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妒挎,居然都是意外死亡绳锅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門酝掩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鳞芙,“玉大人,你說我怎么就攤上這事≡” “怎么了驯嘱?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喳坠。 經(jīng)常有香客問我鞠评,道長,這世上最難降的妖魔是什么壕鹉? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任剃幌,我火速辦了婚禮,結(jié)果婚禮上晾浴,老公的妹妹穿的比我還像新娘负乡。我一直安慰自己,他們只是感情好怠肋,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布敬鬓。 她就那樣靜靜地躺著,像睡著了一般笙各。 火紅的嫁衣襯著肌膚如雪钉答。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天杈抢,我揣著相機與錄音数尿,去河邊找鬼。 笑死惶楼,一個胖子當著我的面吹牛右蹦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歼捐,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼何陆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了豹储?” 一聲冷哼從身側(cè)響起贷盲,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剥扣,沒想到半個月后巩剖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡钠怯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年佳魔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晦炊。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鞠鲜,死狀恐怖宁脊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情镊尺,我是刑警寧澤朦佩,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布并思,位于F島的核電站庐氮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宋彼。R本人自食惡果不足惜弄砍,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望输涕。 院中可真熱鬧音婶,春花似錦、人聲如沸莱坎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檐什。三九已至碴卧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乃正,已是汗流浹背住册。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓮具,地道東北人荧飞。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像名党,于是被迫代替她去往敵國和親叹阔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354