Posted on 2012-12-14 11:01
鑫龍 閱讀(211)
評論(0) 編輯 收藏 引用 所屬分類:
linux編程
線程的分離狀態決定一個線程以什么樣的方式來終止自己。
線程的默認屬性,一般是非分離狀態,
這種情況下,原有的線程等待創建的線程結束。
只有當pthread_join()函數返回時,創建的線程才算終止,才能釋放自己占用的系統資源。
而分離線程沒有被其他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統資源。
程序員應該根據自己的需要,選擇適當的分離狀態。
關于分離線程的一種用法(轉)
講到分離線程,先得從僵尸進程講起(抱歉,確實不知道線程是否有僵尸一說)。
關于僵尸進程:一般情況下進程終止的時候,和它相關的系統資源也并不是主動釋放的,而是進入一種通常稱為“僵尸”(zombie)的狀態。它所占有 的資源一直被系統保留,直到它的父進程(如果它直接的父進程先于它去世,那么它將被init進程所收養,這個時候init就是它的父進程)顯式地調用 wait系列函數為其“收尸”。為了讓父進程盡快知道它去世的消息,它會在它死去的時候通過向父進程發送SIGCHLD信號的方式向其“報喪”。
所以一旦父進程長期運行,而又沒有顯示wait或者waitpid,同時也沒處理SIGCHLD信號,這個時候init進程,就沒辦法來替子進程來收尸。這個時候,子進程就真的成了”僵尸“了。
同理:
如果一個線程調用了這個函數,那么當這個線程終止的時候,和它相關的系統資源將被自動釋放,系統不用也不能用pthread_join()等待其退 出。有的時候分離線程更好些,因為它潛在地減少了一個線程回收的同步點,并且pthread_join()這個API確實也是相當地難用。
為了讓主線程省去去子線程收尸的過程,可以使用
int pthread_detach(pthread_t thread);
來讓子線程處于分離狀態,就不需要父線程再pthread_join了。
我們來看一種分離線程的用法。上次別人問道一種情況,我發現必須要分離子線程:
void* task1(void*);
void usr();
int p1;
int main()
{
p1=0;
usr(); //調用這個認為是你的觸發函數
getchar();
return 1;
}
void usr()
{
pthread_t pid1;
pthread_attr_t attr;
/*這里做你的事情*/
if(p1==0)
{ pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //因為你的線程不便于等待的關系,設置為分離線程吧
pthread_create(&pid1, &attr, task1, NULL);
}
}
void* task1(void *arg1)
{
p1=1; //讓子線程不會被多次調用
int i=0;
printf("thread1 begin./n");
for(i=0;i<100;i++)
{
sleep(2);
printf("At thread1: i is %d/n",i);
usr(); //繼續調用
}
pthread_exit();
}
我 們看到,在這里task1這個線程函數居然會多次調用其父線程里的函數,顯然usr函數里,我們無法等待task1結束,反而task1會多次調用 usr,一旦我們在usr里pthread_join,則在子線程退出前,有多個usr函數會等待,很浪費資源。所以,此處,將task1設置為分離線程 是一種很好的做法。