一. pthread_create()
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
pthread_t *thread: 傳遞一個pthread_t變量地址進來,用於保存新線程的tid(線程ID)
const pthread_attr_t *attr: 線程屬性設置,如使用默認屬性,則傳NULL
void *(*start_routine) (void *): 函數指針,指向新線程應該加載執行的函數模塊
void *arg: 指定線程將要加載調用的那個函數的參數
返回值:成功返回0,失敗返回錯誤號。以前學過的系統函數都是成功返回0,失敗返回-1,而錯誤號保存在全局變量errno中,而pthread庫的函數都是通過返回值返回錯誤號,雖然每個線程也都有一個errno,但這是為了兼容其它函數接口而提供的,pthread庫本身並不使用它,通過返回值返回錯誤碼更加清晰。
二.pthread_join()
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
pthread_t thread: 回收線程的tid
void **retval: 接收退出線程傳遞出的返回值
返回值:成功返回0,失敗返回錯誤號
注意:
調用該函數的線程將掛起等待,直到id為thread的線程終止。thread線程以不同的方法終止,通過pthread_join得到的終止狀態是不同的,總結如下:
如果thread線程通過return返回,retval所指向的單元里存放的是thread線程函數的返回值。
如果thread線程被別的線程調用pthread_cancel異常終止掉,retval所指向的單元里存放的是常數PTHREAD_CANCELED。
如果thread線程是自己調用pthread_exit終止的,retval所指向的單元存放的是傳給pthread_exit的參數。
如果對thread線程的終止狀態不感興趣,可以傳NULL給retval參數。
三.pthread_exit()
#include <pthread.h>
void pthread_exit(void *retval);
void *retval: 線程退出時傳遞出的參數,可以是退出值或地址,如是地址時,不能是線程內部申請的局部地址。
注意和exit函數的區別,任何線程里exit導致進程退出,其他線程未工作結束,主線程退出時不能return或exit。需要注意,pthread_exit或者return返回的指針所指向的內存單元必須是全局的或者是用malloc分配的,不能在線程函數的棧上分配,因為當其它線程得到這個返回指針時線程函數已經退出了。
四.pthread_cancel()
#include <pthread.h>
int pthread_cancel(pthread_t thread);
定義在Linux的pthread庫中常數PTHREAD_CANCELED的值是-1。可以在頭文件pthread.h中找到它的定義:
#define PTHREAD_CANCELED ((void *) -1)
五.示例
#include <pthread.h> #include <stdio.h> #include <unistd.h> void *thr_fn1(void *arg) { printf("thread 1 returning\n"); return (void*)1; } void *thr_fn2(void *arg) { printf("thread 2 exiting\n"); pthread_exit((void*)2); } void *thr_fn3(void *arg) { while(1) { printf("thread 3 writing\n"); sleep(1); } } int main() { pthread_t tid; void *retval; pthread_create(&tid, NULL, thr_fn1, NULL); pthread_join(tid, &retval); printf("thread 1 exit code %d\n", (int)retval); pthread_create(&tid, NULL, thr_fn2, NULL); pthread_join(tid, &retval); printf("thread 2 exit code %d\n", (int)retval); pthread_create(&tid, NULL, thr_fn3, NULL); sleep(3); // 調用pthread_cancel函數取消第三個線程 pthread_cancel(tid); // 如果線程是通過pthread_cancel異常終止掉,retval所指向的單元里存放的是常數PTHREAD_CANCELED pthread_join(tid, &retval); printf("thread 3 exit code %d\n", (int)retval); return 0; }
運行結果:
thread 1 returning
thread 1 exit code 1
thread 2 exiting
thread 2 exit code 2
thread 3 writing
thread 3 writing
thread 3 writing
thread 3 exit code -1