创建线程
pthread_self函數(shù)
獲取線程ID。其作用對應(yīng)進程中 getpid() 函數(shù)。
?????? pthread_t pthread_self(void);????? 返回值:成功:0;???? 失敗:無!
?????? 線程ID:pthread_t類型,本質(zhì):在Linux下為無符號整數(shù)(%lu),其他系統(tǒng)中可能是結(jié)構(gòu)體實現(xiàn)
?????? 線程ID是進程內(nèi)部,識別標志。(兩個進程間,線程ID允許相同)
?????? 注意:不應(yīng)使用全局變量 pthread_t tid,在子線程中通過pthread_create傳出參數(shù)來獲取線程ID,而應(yīng)使用pthread_self。
pthread_create函數(shù)
創(chuàng)建一個新線程。???????????? 其作用,對應(yīng)進程中fork() 函數(shù)。
?????? int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
?????? 返回值:成功:0;???? 失敗:錯誤號????? -----Linux環(huán)境下,所有線程特點,失敗均直接返回錯誤號。
參數(shù):??
?????? pthread_t:當(dāng)前Linux中可理解為:typedef? unsigned long int? pthread_t;
參數(shù)1:傳出參數(shù),保存系統(tǒng)為我們分配好的線程ID
?????? 參數(shù)2:通常傳NULL,表示使用線程默認屬性。若想使用具體屬性也可以修改該參數(shù)。
?????? 參數(shù)3:函數(shù)指針,指向線程主函數(shù)(線程體),該函數(shù)運行結(jié)束,則線程結(jié)束。
?????? 參數(shù)4:線程主函數(shù)執(zhí)行期間所使用的參數(shù)。
在一個線程中調(diào)用pthread_create()創(chuàng)建新的線程后,當(dāng)前線程從pthread_create()返回繼續(xù)往下執(zhí)行,而新的線程所執(zhí)行的代碼由我們傳給pthread_create的函數(shù)指針start_routine決定。start_routine函數(shù)接收一個參數(shù),是通過pthread_create的arg參數(shù)傳遞給它的,該參數(shù)的類型為void *,這個指針按什么類型解釋由調(diào)用者自己定義。start_routine的返回值類型也是void *,這個指針的含義同樣由調(diào)用者自己定義。start_routine返回時,這個線程就退出了,其它線程可以調(diào)用pthread_join得到start_routine的返回值,類似于父進程調(diào)用wait(2)得到子進程的退出狀態(tài),稍后詳細介紹pthread_join。
pthread_create成功返回后,新創(chuàng)建的線程的id被填寫到thread參數(shù)所指向的內(nèi)存單元。我們知道進程id的類型是pid_t,每個進程的id在整個系統(tǒng)中是唯一的,調(diào)用getpid(2)可以獲得當(dāng)前進程的id,是一個正整數(shù)值。線程id的類型是thread_t,它只在當(dāng)前進程中保證是唯一的,在不同的系統(tǒng)中thread_t這個類型有不同的實現(xiàn),它可能是一個整數(shù)值,也可能是一個結(jié)構(gòu)體,也可能是一個地址,所以不能簡單地當(dāng)成整數(shù)用printf打印,調(diào)用pthread_self(3)可以獲得當(dāng)前線程的id。
attr參數(shù)表示線程屬性,本節(jié)不深入討論線程屬性,所有代碼例子都傳NULL給attr參數(shù),表示線程屬性取缺省值,感興趣的讀者可以參考APUE。
【練習(xí)】:創(chuàng)建一個新線程,打印線程ID。注意:鏈接線程庫 -lpthread? ???????????????????? ???????????????????? 【pthrd_crt.c】
由于pthread_create的錯誤碼不保存在errno中,因此不能直接用perror(3)打印錯誤信息,可以先用strerror(3)把錯誤碼轉(zhuǎn)換成錯誤信息再打印。如果任意一個線程調(diào)用了exit或_exit,則整個進程的所有線程都終止,由于從main函數(shù)return也相當(dāng)于調(diào)用exit,為了防止新創(chuàng)建的線程還沒有得到執(zhí)行就終止,我們在main函數(shù)return之前延時1秒,這只是一種權(quán)宜之計,即使主線程等待1秒,內(nèi)核也不一定會調(diào)度新創(chuàng)建的線程執(zhí)行,下一節(jié)我們會看到更好的辦法。
【練習(xí)】:循環(huán)創(chuàng)建多個線程,每個線程打印自己是第幾個被創(chuàng)建的線程。(類似于進程循環(huán)創(chuàng)建子進程)? ??????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?????????????????????????????????? ?? ? 【more_pthrd.c】
拓展思考:將pthread_create函數(shù)參4修改為(void *)&i, 將線程主函數(shù)內(nèi)改為 i=*((int *)arg) 是否可以?
/*** pthread_create.c ***/ #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<pthread.h> #include<string.h> void *thrd_func(void *arg) {printf("In thread : thread id = %lu,pid = %u\n",pthread_self(),getpid());return NULL;}int main() {pthread_t tid;int ret;printf("In main 1 : thread id = %lu,pid = %ui\n",pthread_self(),getpid());ret = pthread_create(&tid,NULL,thrd_func,NULL);if(0 != ret){fprintf(stderr,"pthread_create error:%s\n",strerror(ret));exit(1); }sleep(1);printf("In main 2 : thread id = %lu,pid = %u\n",pthread_self(),getpid());return 0; }運行結(jié)果:
ubuntu1604@ubuntu:~/wangqinghe/linux/20190814$ ./pthread_create
In main 1 : thread id = 140573795596032,pid = 3648i
In thread : thread id = 140573787256576,pid = 3648
In main 2 : thread id = 140573795596032,pid = 3648
?
循環(huán)創(chuàng)建多個子線程 /*** mul_pthread.c ***/ #include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<stdlib.h>void *thrd_func(void *arg) {int i = (int)arg;sleep(i);printf("%dth thread: thread id = %lu,pid = %u\n",i+1,pthread_self(),getpid());return NULL; }int main() {pthread_t tid;int ret,i;for(i = 0; i < 5; i++){ret = pthread_create(&tid,NULL,thrd_func,(void *)i);if(0 != ret){fprintf(stderr,"pthrea_create error:%s\n",strerror(ret));exit(1);}}sleep(i);return 0; }運行結(jié)果:
ubuntu1604@ubuntu:~/wangqinghe/linux/20190814$ ./mul_pthread
1th thread: thread id = 140132717160192,pid = 4026
2th thread: thread id = 140132708767488,pid = 4026
3th thread: thread id = 140132700374784,pid = 4026
4th thread: thread id = 140132691982080,pid = 4026
5th thread: thread id = 140132683589376,pid = 4026
?
轉(zhuǎn)載于:https://www.cnblogs.com/wanghao-boke/p/11376360.html
總結(jié)
- 上一篇: 试管取卵后会导致卵巢早衰吗
- 下一篇: 线程退出