關於POSIX thread的最基本用法
要用到線程,但對線程一直不怎麼懂,看了些資料作了兩個例子和總結,不對的地方懇請各位指正。
1.基本函數
pthread_create,pthread_detach,pthread_join,pthread_exit,pthread_self
具體的意義和參數看man或者書吧,其他的函數還不會用。
2.基本用法
程序1
程序功能:main產生一個線程,線程根據main傳來的參數產生幾個60-100的隨機數;main待線程退出後退出。
#include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <time.h> int myRand(void* cnt) { int min = 60; int max = 100; int randCnt = *((int *)cnt); int i = 0; pthread_t thread_id = pthread_self(); /* init the random seed */ srand((unsigned int)time(NULL)); for(; i < randCnt; i ++) { /* create random number in [60, 100) */ printf("thread_id = %d rand()%02d = %d/n", thread_id, i, min + rand() % (max - min)); sleep(1); } //return 11; pthread_exit((void*)11); } int main(int argc, char* argv[]) { pthread_t tid; void* result; int reqRandCnt = 5; if(pthread_create(&tid, NULL, (void *)myRand, (void *)&reqRandCnt) == 0) { printf("myRand thread create OK!/n"); //pthread_detach(tid); } if(pthread_join(tid, &result) == 0) { printf("thread tid = %d, result = %d/n", tid, (int)result); } return 0; //pthread_exit((void*)22); }
一次運行結果:
thread_id = 1082367168 rand()00 = 95
myRand thread create OK!
thread_id = 1082367168 rand()01 = 71
thread_id = 1082367168 rand()02 = 63
thread_id = 1082367168 rand()03 = 81
thread_id = 1082367168 rand()04 = 66
thread tid = 1082367168, result = 11
幾點說明
1) main用pthread_create產生一個線程,最主要的是後第三第四個參數,第三參數是完成線程的函數,第四參數是傳給線程的參數。這裏傳的是一個整數,如果線程完成的功能改爲根據main需要產生x個值在[m, n)的隨機數,可以將三個參數定義一個構造體傳給線程。
2) main用pthread_join等待線程完成退出後再退出,類似進程的wait函數。值得注意的是該函數的第二個參數,它指向線程的返回值,用了一個二級指針,不怎麼明白。
另外pthread_join與pthread_detach只能用其一。詳見參考資料。
<參考資料語>
一般情況下,進程中各個線程的運行都是相互獨立的,線程的終止並不會通知,也不會影響其他線程,終止的線程所佔用的資源也並不會隨着線程的終止而得到釋 放。正如進程之間可以用wait()系統調用來同步終止並釋放資源一樣,線程之間也有類似機制,那就是pthread_join()函數
pthread_join()的調用者將掛起並等待th線程終止,retval是pthread_exit()調用者線程(線程ID爲th)的返回值,如 果thread_return不爲NULL,則*thread_return=retval。需要注意的是一個線程僅允許唯一的一個線程使用 pthread_join()等待它的終止,並且被等待的線程應該處於可join狀態,即非DETACHED狀態
如果進程中的某個線程執行了pthread_detach(th),則th線程將處於DETACHED狀態,這使得th線程在結束運行時自行釋放所佔用的 內存資源,同時也無法由pthread_join()同步,pthread_detach()執行之後,對th請求pthread_join()將返回錯誤
一個可join的線程所佔用的內存僅當有線程對其執行了pthread_join()後纔會釋放,因此爲了避免內存泄漏,所有線程的終止,要麼已設爲DETACHED,要麼就需要使用pthread_join()來回收
3) 主線程用pthread_exit還是return
用pthread_exit只會使主線程自身退出,產生的子線程繼續執行;用return則所有線程退出。
綜合以上要想讓子線程總能完整執行(不會中途退出),一種方法是在主線程中調用pthread_join對其等待,即pthread_create/pthread_join/pthread_exit或return;一種方法是在主線程退出時使用pthread_exit,這樣子線程能繼續執行,即pthread_create/pthread_detach/pthread_exit;還有一種是pthread_create/pthread_detach/return,這時就要保證主線程不能退出,至少是子線程完成前不能退出。現在的項目中用的就是第三種方法,主線程是一個死循環,子線程有的是死循環有的不是。
<參考資料語>
理論上說,pthread_exit()和線程宿體函數退出的功能是相同的,函數結束時會在內部自動調用pthread_exit()來清理線程相關的資源。但實際上二者由於編譯器的處理有很大的不同。
在進程主函數(main())中調用pthread_exit(),只會使主函數所在的線程(可以說是進程的主線程)退出;而如果是return,編譯器將使其調用進程退出的代碼(如_exit()),從而導致進程及其所有線程結束運行。