關(guān)于線程用法可以參考這些文章
一搞乏、Linux中 C/C++線程使用
三仗考、linux中pthread_join()與pthread_detach()解析
四音同、linux中pthread_cond_wait()與pthread_cond_signal ()解析
Note: 關(guān)于內(nèi)核使用線程方法可以參考之前寫的另外一篇文章
這篇文章主要是介紹 pthread兩種狀態(tài): joinable狀態(tài)和unjoinable狀態(tài)
- 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);
- 如果線程是joinable狀態(tài)锅锨,當線程函數(shù)自己返回退出時或pthread_exit時都不會釋放線程所占用堆棧和線程描述符(總計8K多)叽赊。只有當你調(diào)用了pthread_join之后這些資源才會被釋放。
- 若是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!