1. 程式人生 > >關於分離執行緒

關於分離執行緒

執行緒的分離狀態決定一個執行緒以什麼樣的方式來終止自己。
執行緒的預設屬性,一般是非分離狀態,
這種情況下,原有的執行緒等待建立的執行緒結束。
只有當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設定為分離執行緒 是一種很好的做法。