linux中線程如何退出

             在Linux中,默認情況下是在一個線程被創建後,必須使用此函數對創建的線程進行資源回收,但是可以設置Threads attributes來設置當一個線程結束時,直接回收此線程所佔用的系統資源,詳細資料查看Threads attributes。

其實在Linux中,新建的線程並不是在原先的進程中,而是系統通過一個系統調用clone()。該系統調用copy了一個和原先進程完全一樣的進程,並在這個進程中執行線程函數。不過這個copy過程和fork不一樣。 copy後的進程和原先的進程共享了所有的變量,運行環境。這樣,原先進程中的變量變動在copy後的進程中便能體現出來。
pthread_join的應用
pthread_join使一個線程等待另一個線程結束。
代碼中如果沒有pthread_join主線程會很快結束從而使整個進程結束,從而使創建的線程沒有機會開始執行就結束了。加入pthread_join後,主線程會一直等待直到等待的線程結束自己才結束,使創建的線程有機會執行。
所有線程都有一個線程號,也就是Thread ID。其類型爲pthread_t。通過調用pthread_self()函數可以獲得自身的線程號。

2使用範例編輯

一個線程的結束有兩種途徑,一種是象我們下面的例子一樣,函數結束了,調用它的線程也就結束了;另一種方式是通過函數pthread_exit來實現。另外需要說明的是,一個線程不能被多個線程等待,也就是說對一個線程只能調用一次pthread_join,否則只有一個能正確返回,其他的將返回ESRCH 錯誤。
在Linux中,默認情況下是在一個線程被創建後,必須使用此函數對創建的線程進行資源回收,但是可以設置Threads attributes來設置當一個線程結束時,直接回收此線程所佔用的系統資源,詳細資料查看Threads attributes。
範例:
//signaltest.c
  // 子線程阻塞,等待信號,然後輸出字符串
  // 主線程從鍵盤錄入字符,給子線程發信號。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<pthread.h>
#include<time.h>
pthread_ttid; sigset_tset;
voidmyfunc()
{
 printf("hello\n");
}
staticvoid*mythread(void*p)
{
 intsignum;
 while(1){
 sigwait(&set,&signum);
 if(SIGUSR1==signum)
 myfunc();
 if(SIGUSR2==signum)
 {
 printf("Iwillsleep2secondandexit\n");
 sleep(2);
 break;
 }
}
}
intmain()
{
chartmp;
void*status;
sigemptyset(&set);
sigaddset(&set,SIGUSR1);
sigaddset(&set,SIGUSR2);
sigprocmask(SIG_SETMASK,&set,NULL);
pthread_create(&tid,NULL,mythread,NULL);
while(1)
{
printf(":");
scanf("%c",&tmp);
if('a'==tmp)
{
pthread_kill(tid,SIGUSR1);//發送SIGUSR1,打印字符串。
}
elseif('q'==tmp)
{
//發出SIGUSR2信號,讓線程退出,如果發送SIGKILL,線程將直接退出。
pthread_kill(tid,SIGUSR2);
//等待線程tid執行完畢,這裏阻塞。
pthread_join(tid,&status);
printf("finish\n");
break;
}
else
continue;
}
return0;
}
運行結果:
// 如果輸入a,子線程打印"hello",主程序繼續等待輸入;
// 如果輸入q,主程序等待子程序結束。子線程打印"I will sleep 2 second and exit",並延時兩秒後結束。主線程隨之打印"finish",程序結束。
在前面我們提到,可以通過pthread_join()函數來使主線程阻塞等待其他線程退出,這樣主線程可以清理其他線程的環境。但是還有一些線程,更喜歡自己來清理退出的狀態,他們也不願意主線程調用pthread_join來等待他們。我們將這一類線程的屬性稱爲detached。如果我們在調用pthread_create()函數的時候將屬性設置爲NULL,則表明我們希望所創建的線程採用默認的屬性,也就是joinable。如果需要將屬性設置爲detached,則參考下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void*start_run(void*arg)
{
//dosomework
}
 
intmain()
{
pthread_tthread_id;
pthread_attr_tattr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&thread_id,&attr,start_run,NULL);
pthread_attr_destroy(&attr);
sleep(5);
exit(0);
}
在線程設置爲joinable後,可以調用pthread_detach()使之成爲detached。但是相反的操作則不可以。還有,如果線程已經調用pthread_join()後,則再調用pthread_detach()則不會有任何效果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章