關于Linux下的多線程
一、線程的創建
頭文件
#include <pthread.h>
函數聲明
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
在一個線程中調用pthread_create函數創建新的線程后,當前線程從pthread_create處繼續往下執行,start_routine為新創建線程的入口函數,start_routine函數接收一個參數,是通過pthread_create的arg參數傳遞給它的,該參數的類型為void* ,這個指針按什么類型解釋由調用者自己定義,start_routine的返回值類型也是void,這個指針的含義同樣由調用者自己定義,start_routine返回時,這個線程就退出了,其它線程可以調用pthread_join得到start_routine的返回值。
參數說明
第一個參數為指向線程標識符的指針。
第二個參數用來設置線程屬性,用于指定各種不同的線程屬性。
第三個參數是線程運行函數的起始地址,該函數只有一個萬能指針參數arg,如果需要向start_rtn函數傳遞的參數不止一個,那么需要把這些參數放到一個結構中,然后把這個結構的地址作為arg的參數傳入。
最后一個參數是運行函數的參數。
返回值
若線程創建成功,則返回0,若線程創建失敗,則返回出錯編號,并且*thread中的內容是未定義的。
第一個簡單的線程程序
#include <stdio.h> #include <pthread.h> void printThread(const char *s) { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int) pid, (unsigned int) tid, (unsigned int) tid); } void* run(void* arg) { printThread("new thread: "); return NULL; } int main(void) { pthread_t pt; int err = pthread_create(&pt, NULL, run, NULL); if (err != 0) printf("can't create thread: %s\n", strerror(err)); printThread("main thread:"); pthread_join(pt, NULL); return 0; } |
注意
因為pthread并非Linux系統的默認庫,而是POSIX線程庫。在Linux中將其作為一個庫來使用,因此加上 -lpthread(或-pthread)以顯式鏈接該庫。
$g++ main.cpp -lpthread -o main
$./main
二、pthread_join函數
函數聲明
int pthread_join(pthread_t thread, void **retval);
參數說明
thread: 線程標識符,即線程ID,標識唯一線程。
retval: 用戶定義的指針,用來存儲被等待線程的返回值。
描述
pthread_join函數,阻塞當前線程的執行,以等待thread指定的線程結束。當函數返回時,被等待線程的資源被收回。如果進程已經結束,那么該函數會立即返回。并且thread指定的線程必須是joinable的,新創建的線程默認就是joinable的。
三、線程的兩種狀態:joinable(默認)和detached
joinable線程可以被其他線程回收,在被其他線程回收之前,它所占用的存儲器資源并不被釋放,而detached線程不能被其他線程回收,它占用的存儲器資源由系統自動釋放。
在默認情況下,線程是joinable的,只有當pthread_join函數返回時,創建的線程才算終止,才能釋放自己占用的系統資源,而detached線程沒有被其他線程等待,線程執行完畢立馬釋放系統資源。
設置線程狀態的函數pthread_attr_setdetachstate,函數聲明為pthread_attr_setdetachstate(pthread_attr_t* attr, int detachstate);其中第二個參數是可選的PTHREAD_CREATE_DETACHED(分離線程)和 PTHREAD _CREATE_JOINABLE(非分離線程)。
如果設置一個線程為分離線程,而這個線程運行又非常快,它很可能在pthread_create函數返回之前就終止了,它終止以后就可能將線程號和系統資源移交給其他的線程使用,這樣調用pthread_create的線程就得到了錯誤的線程號。要避免這種情況可以采取一定的同步措施,最簡單的方法之一是可以在被創建的線程里調用pthread_cond_timewait函數,讓這個線程等待一會兒,留出足夠的時間讓函數pthread_create返回。設置一段等待時間,是在多線程編程里常用的方法。但是注意不要使用諸如 wait 之類的函數,它們是使整個進程睡眠,并不能解決線程同步的問題。
如果進程中的某個線程執行了pthread_detach(th),則th線程將處于DETACHED狀態,這使得th線程在結束運行時自行釋放所占用的內存資源,同時也無法由pthread_join()同步,pthread_detach()執行之后,對th請求pthread_join()將返回錯誤。
四、linux下多線程屬性設置
attr的缺省屬性值
pthread_attr_t attr;
初始化屬性
pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_init 成功完成后將返回0,其他任何返回值都表示出現了錯誤,并將返回對應的值。 |
銷毀屬性
使用 pthread_attr_destroy(&attr) 刪除初始化期間分配的存儲空間,屬性對象將會無效,函數成功完成后將返回0,其他任何返回值都表示出現了錯誤,并將返回對應的值。
posted on 2014-02-25 10:37 順其自然EVO 閱讀(248) 評論(0) 編輯 收藏 所屬分類: linux