The Pthreads API
Pthreads API可以非正式地分爲以下四組:
- 線程管理:
- 互斥:
- 條件變量:
- 同步:
線程管理
API:
#include <pthread.h>
int pthread_create(pthread_t *thread, pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
void pthread_exit(void *value_ptr);
int pthread_cancel(pthread_t thread);
int pthread_attr_destroy(pthread_attr_t *attr);
int pthread_attr_init(pthread_attr_t *attr);
創建線程:
- 最初main程序由一個默認線程組成,其他線程必須顯示地創建
- pthread_create創建一個線程然後執行,可以在代碼中的任意地方調用
- pthread_create的參數
- thread:返回新創建線程的獨一無二的標識符
- attr:用於設定線程屬性的屬性對象,NULL爲默認值
- start_routine: 需要線程執行的例程(函數的入口地址,也就是函數的指針)
- arg: 傳遞給start_routine例程的參數,類型爲void*
- 一個進程可創建的最大線程數是由不同操作系統決定的
- ulimit -a
線程屬性(thread attribute object):
- 默認情況下,被創建的線程帶有一種屬性。我們可以用屬性對象來改變線程的屬性。
- pthread_attr_init 和 pthread_attr_destroy 用於初始化/銷燬線程屬性。
- 其他例程用於設定或查詢線性屬性,其中包括:
- Detached or joinable state
- Scheduling inheritance
- Scheduling policy
- Scheduling parameters
- Scheduling contention scope
- Stack size
- Stack address
- Stack guard (overflow) size
線程綁定和調度
終止線程
- 有多種方法來終止線程
- 從start_routine正常返回
- 線程調用pthread_exit
- 線性調用pthread_cancel來終止其他線程
- 調用exec() 或exit() 來結束整個進程
- main() 結束
- pthread_exit() 允許指定一個終止狀態碼
- pthread_exit() 並不關閉打開的文件
加入(Joining) 和 分離(Detaching) 線程
API:
int pthread_join(pthread_t threadid, void **value_ptr);
int pthread_detach(pthread_t thread);
int pthread_attr_getdetachstate(pthread_attr_t *attr,
int *detachstate);
int pthread_attr_setdetachstate(pthread_attr_t *attr,
int detachstate);
Joining:
- pthread_join()例程阻塞調用線程,直到指定的線程標識爲threadid的線程終止
- pthread_join()可以獲得目標線程的終止狀態
- 如果調用pthread_join()被canceled,那麼目標進程就不會被分離
- 同時對同一個目標線程調用pthread_join()的結果是未定義的
- 如果pthread_join()成功返回,實現目標線程的資源將被回收,例如線程棧空間
Detaching
- pthread_detach()可以使目標線程進入分離狀態
- 進入分離狀態的線程在終止時會自動回收線程資源
棧管理
API:
int pthread_attr_getstacksize(pthread_attr_t *attr,
size_t *stacksize);
int pthread_attr_setstacksize(pthread_attr_t *attr,
size_t stacksize);
int pthread_attr_getstackaddr(pthread_attr_t *attr,
void **restrict stackaddr);
int pthread_attr_setstackaddr(pthread_attr_t *attr,
void *stackaddr);
互斥量(Mutex Variables)
API:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *mutex,pthread_mutexattr_t *attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
使用:
- 互斥量使用之前必須初始化,有兩種方法進行初始化
- 靜態聲明時 pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
- 動態分配 pthread_mutex_init()
- attr目標用於去建立互斥鎖的屬性,Pthreads標準定義了三個屬性:
- Process-shared:
- Protocol
- Prioceiling
- pthread_mutexattr_init() 和 pthread_mutexattr_destroy()用於創建和銷燬互斥鎖屬性
Locking 與 Unlocking 互斥鎖:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
- pthread_mutex_unlock()會返回錯誤如果當前進程沒有獲得這把鎖或者這把鎖已經unlock
條件變量(Condition Variables)
API:
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t* cond,pthread_condattr_t *attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);