在linux中的多線程一節中,我們介紹了利用pthread_create()函數建立子線程的方法。這種方式建立的線程存在一個問題:在主線程建立完成子線程後,若子線程函數
還沒結束時,但是此時主線程函數已經結束,那麼子線程也會被強制銷毀,為了避免這個問題,當時我們在主線程中sleep了11秒鐘以等待子線程的結束。雖然暫時避免了問題的發生,但是顯然這不是很友好的解決方案,因為在實際程式設計中你無法預料子線程什麼時候會結束,也就無法給出準确的sleep的時間。
本文主要讨論下利用pthread_join()函數解決這個問題,首先,看一下函數的原型:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
pthread_join的第一個參數是建立的子線程線程ID,第二個參數是子線程函數的傳回值位址的指針,也就是其傳回值位址的位址。pthread_join的作用就是等待第一個參數指定的線程的結束,在等待期間該函數是阻塞的,等到子線程結束後,函數結束阻塞狀态。下面我們就在代碼中示範下pthread_join的用法:
#include<stdio.h>
#include<pthread.h>
void* thread_main(void* pmax)
{
int i;
int max=*((int*)pmax);
for(i=0;i<max;i++)
{
puts("child thread called...");
sleep(1);
}
return "Tread ended ...";
}
int main()
{
pthread_t pid;
void* rst;
int max=10;
pthread_create(&pid,NULL,(void*)thread_main,(void*)&max);
pthread_join(pid,(void*)&rst);
printf("the child return: %s\n",(char*)rst);
return 0;
}
第4行我們定義了一個線程的主函數thread_main;
第21行利用pthread_create()函數建立了一個線程,分别将通過pid擷取到了線程ID、傳入線程函數,然後利用max傳入線程函數的參數。
第22行調用pthread_join()函數等待線程的結束,通過函數的第一個參數指定要等待的線程,第二個參數用來接收線程函數傳回值,注意rst是一個void**的指針。
最後列印出線程函數的傳回值。
至此,我們沒有使用sleep()函數使主線程睡,也完美實作了等待子線程的結束,來看下運作結果:
[[email protected] multithread]$ gcc ts.c -lpthread
[[email protected] multithread]$ ./a.out
child thread called...
child thread called...
child thread called...
child thread called...
child thread called...
child thread called...
child thread called...
child thread called...
child thread called...
child thread called...
the child return: Tread ended ...
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本項目:
git clone [email protected]:HymanLiuTS/NetDevelopment.git
擷取本文源代碼:
git checkout NL35