线程控制原语之pthread_self和pthread_create函数
注意:使用線程庫函數用gcc編譯時,要加參數:-lpthread(libpthread.so),因為線程庫函數屬于第三方c庫函數,不是標準庫函數(/lib、/usr/lib或者/usr/local/lib)。
(1)pthread_self函數
獲取線程ID。其作用對應進程中 getpid() 函數。
pthread_t pthread_self(void);?? 返回值:成功:調用該函數的線程ID;失敗:永遠不會失敗。
pthread_t:typedef? unsigned long int? pthread_t;? 輸出格式格式為:%lu
線程ID是進程內部,識別標志。(兩個進程間,線程ID允許相同)
注意:不應使用全局變量 pthread_t tid(因為全局變量被一個進程中的多個線程共享),在子線程中通過pthread_create傳出參數來獲取線程ID或者使用pthread_self。
(2)pthread_create函數
創建一個新線程。其作用對應進程中fork() 函數。
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
返回值:成功:0;失敗:錯誤編號。Linux環境下,所有線程特點,失敗均直接返回錯誤編號,即直接返回errno number。
參數1:傳出參數,新建線程的線程ID
參數2:傳入參數,通常傳NULL,表示使用線程默認屬性。若想使用具體屬性也可以修改該參數。
參數3:函數指針,指向線程主控函數(線程體),該函數運行結束,則線程結束。
參數4:線程主函數執行期間所使用的參數,若不同參數傳NULL。
在一個線程中調用pthread_create()創建新的線程后,當前線程從pthread_create()返回繼續往下執行,而新的線程所執行的代碼由我們傳給pthread_create的函數指針start_routine決定(線程創建成功后就立即去執行start_routine函數)。start_routine函數接收一個參數,是通過pthread_create的arg參數傳遞給它的,該參數的類型為void *,這個指針按什么類型解釋由調用者自己定義。start_routine的返回值類型也是void *,這個指針的含義同樣由調用者自己定義。start_routine返回時,這個線程就退出了,其它線程可以調用pthread_join得到start_routine的返回值,類似于父進程調用wait( )得到子進程的退出狀態,稍后詳細介紹pthread_join。
pthread_create成功返回后,新創建的線程的id被填寫到thread參數所指向的內存單元。我們知道進程id的類型是pid_t,每個進程的id在整個系統中是唯一的,調用getpid( )可以獲得當前進程的id,是一個正整數值。線程id的類型是pthread_t,它只在當前進程中保證是唯一的,在不同的系統中pthread_t這個類型有不同的實現,它可能是一個整數值,也可能是一個結構體,也可能是一個地址,所以不能簡單地當成整數(%lu)用printf打印,調用pthread_self( )可以獲得當前線程的id。
attr參數表示線程屬性,本節不深入討論線程屬性,所有代碼例子都傳NULL給attr參數,表示線程屬性取缺省值,感興趣的讀者可以參考APUE。
//pthread_self和pthread_create函數示例
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h> #include <unistd.h>void *tfn(void *arg) {printf("In thread, the process id is %d and thread id is %lu.\n",getpid( ),pthread_self( ));return NULL; }int main(void) {pthread_t tid;int ret;printf("In main1, the process id is %d and thread id is %lu.\n",getpid( ),pthread_self( ));ret = pthread_create(&tid, NULL, tfn, NULL);if( ret != 0 ) //出錯判斷{fprintf(stderr,"pthread_create error: %s\n",strerror(ret));exit(1);}printf("the created thread's id is %lu\n",tid);sleep(1); //注意一定要睡1sprintf("In main2, the process id is %u and thread id is %lu.\n",getpid( ),pthread_self( ));return 0; }[root@localhost 01_pthread_test]# ./pthrd_crt
In main1, the process id is 9814 and thread id is 4151932608.
the created thread's id is 4149869376
In thread, the process id is 9814 and thread id is 4149869376.
In main2, the process id is 9814 and thread id is 4151932608.
分析:
總結:由于pthread_create的錯誤碼不保存在errno中,因此不能直接用perror( )打印錯誤信息,可以先用strerror( )把錯誤碼轉換成錯誤信息再打印。為了防止新創建的線程還沒有得到執行就終止,我們在main函數return之前延時1秒,這只是一種權宜之計,即使主線程等待1秒,內核也不一定會調度新創建的線程執行,后面會有更好的辦法。
//循環創建n個子線程的架構
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h> #include <unistd.h>void *tfn(void *arg) {int s = (int)arg;sleep(s);printf("The %dth thread: the process id is %d and thread id is %lu.\n",s+1,getpid( ),pthread_self( ));return NULL; }int main(void) {pthread_t tid;int ret, i;for( i=0;i<5;i++ ){ret = pthread_create(&tid, NULL, tfn,(void *)i);if( ret != 0 ){fprintf(stderr,"pthread_create error: %s\n",strerror(ret));exit(1);}}sleep(i);printf("In main: the process id is %u and thread id is %lu.\n",getpid( ),pthread_self( ));return 0; }[root@localhost 01_pthread_test]# ./pthrd_crt
The 1th thread: the process id is 4026 and thread id is 4149246784.
The 2th thread: the process id is 4026 and thread id is 4140854080.
The 3th thread: the process id is 4026 and thread id is 4132461376.
The 4th thread: the process id is 4026 and thread id is 4124068672.
The 5th thread: the process id is 4026 and thread id is 4115675968.
In main: the process id is 4026 and thread id is 4151466240.
分析:
總結
以上是生活随笔為你收集整理的线程控制原语之pthread_self和pthread_create函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 早春二月剧情介绍
- 下一篇: 三星液晶电视怎么样 三星液晶电视质量好吗