POSIX 線程編程小結

The Pthreads API

Pthreads API可以非正式地分爲以下四組:

  1. 線程管理:
  2. 互斥:
  3. 條件變量:
  4. 同步:

線程管理

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);

使用:

  • 互斥量使用之前必須初始化,有兩種方法進行初始化
    1. 靜態聲明時 pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
    2. 動態分配 pthread_mutex_init()
  • attr目標用於去建立互斥鎖的屬性,Pthreads標準定義了三個屬性:
    1. Process-shared:
    2. Protocol
    3. 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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章