POSIX 線程庫功能接口與知識點彙總

POSIX 線程庫功能接口與知識點彙總 linux

—— Linux 平臺 編程

cnyinlinux 2016 元月 西安 多線程

 

     :   /lib64/libpthread.so* 函數

頭文件 :   pthread.h this

 

  spa

第一篇 線程建立與控制 線程

第二篇 線程屬性設置 rest

第三篇 線程同步技術 接口

  進程

本文只是針對POSIX線程庫功能接口與知識點的彙總羅列,僅供多線程編程時查閱參考。

 

第一篇 線程建立與控制

 

1.線程標識符pthread_t

此類型定義以下

/usr/include/bits/pthreadtypes.h : typedef unsigned long int pthread_t ;

 

注:線程有兩重身份:1).線程身份;   2).子進程身份(各線程也具備pid)

 

2.線程建立

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

                          void *(*start_routine) (void *), void *arg);

返回值:0成功

參數:thread 線程ID變量地址,    attr 線程屬性結構地址

      start_routine 線程入口函數,  arg 線程入口函數的參數列表

 

3.線程終止退出函數

void pthread_exit(void *retval);

入參爲退出狀態碼保存地址,通常無視傳入NULL

 

4.線程回收函數

int pthread_join(pthread_t thread, void **retval);

父線程回收子線程時調用,若子線程未退出則掛起等待。

入參爲目標線程的ID和退出狀態,若目標線程被取消,則PTHREAD_CANCELED保存在*retval

 

5.線程分離

int pthread_detach(pthread_t thread);

將子線程分離出去,子線程結束後系統自動回收資源

分離後的子線程可用pthread_join回收(報錯返回)

 

6.線程信號發送

int pthread_kill(pthread_t thread, int sig);

注:線程與進程信號原理同樣,但影響範圍不一樣。不可採用進程的信號處理方式對待線程

單一線程收到進程級信號,則影響整個進程

 

7.線程取消

int pthread_cancel(pthread_t thread);

取消一個線程即終止它,但不是當即結束,而是到下一個取消點到達時

取消點一般位於系統函數中。

人工取消點:void pthread_testcancel(void);

若線程中不存在具備取消點的函數調用,則人工加入取消點函數便可。


8.線程信號屏蔽字

int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);

此用法與進程信號屏蔽字設置函數sigprocmask類似,僅做用範圍不一樣

 

9.線程ID比較函數

int pthread_equal(pthread_t t1, pthread_t t2);

判斷兩個線程ID是否相等

 

10.獲取線程自身ID

pthread_t pthread_self(void);

返回值爲自線程的ID

 

 

第二篇 線程屬性設置

 

1.線程屬性結構 pthread_attr_t

線程大多屬性均可經過該結構體設置,在建立線程時經過pthread_create的第二個參數使其生效。其定義以下

/usr/include/bits/pthreadtypes.h : typedef union pthread_attr_t pthread_attr_t;

/*------------------------------------------------------------*/

# ifdef __x86_64__

# if __WORDSIZE == 64

#  define __SIZEOF_PTHREAD_ATTR_T 56

# else

#  define __SIZEOF_PTHREAD_ATTR_T 32

# endif

# else

# define __SIZEOF_PTHREAD_ATTR_T 36

# endif

union pthread_attr_t

{

   char __size[__SIZEOF_PTHREAD_ATTR_T];

   long int __align;

};

/*------------------------------------------------------------*/

 

2.初始化/銷燬 線程屬性結構體

int pthread_attr_init(pthread_attr_t *attr);

int pthread_attr_destroy(pthread_attr_t *attr);                                                

 

3.設置/獲取 線程分離屬性

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);

線程分離屬性值僅有2個可選項

PTHREAD_CREATE_DETACHED    分離

PTHREAD_CREATE_JOINABLE     未分離

 

4.設置/獲取 線程棧信息

int pthread_attr_setstack(pthread_attr_t *attr,

                                 void *stackaddr, size_t stacksize);

int pthread_attr_getstack(pthread_attr_t *attr,

                                 void **stackaddr, size_t *stacksize);

若指定棧空間,棧大小必須不小於PTHREAD_STACK_MIN

還有兩組關於棧信息的古老函數,建議棄用:

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);    //已過期,棄用

int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);   //已過期,棄用

int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);   //已過期,棄用

int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);  //已過期,棄用

 

5.設置/獲取 棧警惕區大小

int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);

int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);

防止棧溢出而設置的警惕區,應大於0

 

6.設置取消狀態

int pthread_setcancelstate(int state, int *oldstate);

取消狀態有2個可選項

PTHREAD_CANCEL_ENABLE    可取消

PTHREAD_CANCEL_DISABLE    不可取消

 

7.設置取消類型

int pthread_setcanceltype(int type, int *oldtype);

取消類型有2個可選項

PTHREAD_CANCEL_DEFERRED          取消響應在下次取消點到達時

PTHREAD_CANCEL_ASYNCHRONOUS     取消響應爲任意時刻點

 


 

第三篇 線程同步技術

1.線程鎖(互斥量)  pthread_mutext_t

定義在/usr/include/bits/pthreadtypes.h

/*------------------------------------------------------------*/

typedef union

{

   struct __pthread_mutex_s

   {

     int __lock;

     unsigned int __count;

     int __owner;

#ifdef __x86_64__

     unsigned int __nusers;

#endif

     /* KIND must stay at this position in the structure to maintain

        binary compatibility.  */

     int __kind;

#ifdef __x86_64__

     int __spins;

     __pthread_list_t __list;

# define __PTHREAD_MUTEX_HAVE_PREV 1

#else

     unsigned int __nusers;

     __extension__ union

     {

       int __spins;

       __pthread_slist_t __list;

     };

#endif

   } __data;

   char __size[__SIZEOF_PTHREAD_MUTEX_T];

   long int __align;

} pthread_mutex_t;

/*------------------------------------------------------------*/

 

1-0.互斥量的種類:

A. PTHREAD_MUTEX_TIMED_NP

B. PTHREAD_MUTEX_RECURSIVE_NP

C. PTHREAD_MUTEX_ERRORCHECK_NP

D. PTHREAD_MUTEX_ADAPTIVE_NP

E. PTHREAD_MUTEX_FAST_NP

 

 

鎖類型

初始化方式

加解鎖特徵

調度特徵

普通鎖

PTHREAD_MUTEX_INITIALIZER

加鎖一次 解鎖一次

先等待 先得到

嵌套鎖

PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP

同一線程可重複加鎖,解鎖一樣次數纔可釋放

自由競爭

糾錯鎖

PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP

重複加鎖報錯,只能由本線程解鎖

先等待 先得到

自適應鎖

PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP

加鎖一次 解鎖一次

自由競爭



1-1.鎖的初始化/銷燬

pthread_mutex_t mutex;

1). 靜態方式:mutex = PTHREAD_MUTEX_INITIALIZER ;

2). 動態方式:int pthread_mutex_init(pthread_mutex_t *restrict mutex,

                                 const pthread_mutexattr_t *restrict attr);

^鎖的種類由attr結構指定

3).鎖的銷燬 int pthread_mutex_destroy(pthread_mutex_t *mutex);

 

1-2.鎖的屬性設置 pthread_mutexattr_t

A.初始化/銷燬 鎖屬性結構

int pthread_mutexattr_init(pthread_mutexattr_t *attr);

int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);

 

B.設置/獲取 鎖屬性(種類)

int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);

int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);

type可選項:

PTHREAD_MUTEX_NORMAL

PTHREAD_MUTEX_ERRORCHECK

PTHREAD_MUTEX_RECURSIVE

PTHREAD_MUTEX_DEFAULT

PTHREAD_MUTEX_FAST_NP

 

1-3.加鎖/解鎖

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,

                          const struct timespec *restrict abs_timeout);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

 

2.自旋鎖pthread_spinlock_t

與互斥鎖相似,但不釋放CPU,適用於短程佔用高頻搶佔式場景

2-0.自旋鎖初始化/銷燬

int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

int pthread_spin_destroy(pthread_spinlock_t *lock);

注:pshared可選項爲:

PTHREAD_PROCESS_PRIVATE

PTHREAD_PROCESS_SHARED

 

2-1.自旋鎖加解鎖

int pthread_spin_lock(pthread_spinlock_t *lock);

int pthread_spin_trylock(pthread_spinlock_t *lock);

int pthread_spin_unlock(pthread_spinlock_t *lock);

 

3.讀寫鎖pthread_rwlock_t

用於讀多寫少場景

3-0.讀寫鎖初始化/銷燬

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,

              const pthread_rwlockattr_t *restrict attr);

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

 

3-1.讀寫鎖屬性pthread_rwlockattr_t

初始化/銷燬

int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);

int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);

設置/獲取 屬性

int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);

int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *

                                  restrict attr, int *restrict pshared);

pshared可選項爲:

PTHREAD_PROCESS_PRIVATE

PTHREAD_PROCESS_SHARED

 

3-2.讀寫鎖加解鎖

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);     //讀加鎖

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);     //寫加鎖

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);     //解鎖(/ 通吃)

 

4.條件變量pthread_cond_t

事件觸發機制技術,與線程鎖協同使用

4-0.條件變量初始化/銷燬

int pthread_cond_init(pthread_cond_t *restrict cond,

                    const pthread_condattr_t *restrict attr);

int pthread_cond_destroy(pthread_cond_t *cond);

 

4-1.條件變量屬性pthread_condattr_t

初始化/銷燬

int pthread_condattr_init(pthread_condattr_t *attr);

int pthread_condattr_destroy(pthread_condattr_t *attr);

設置/獲取 屬性

int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);

int pthread_condattr_getpshared(const   pthread_condattr_t  *restrict attr,

                                               int *restrict pshared);

pshared可選項爲:

PTHREAD_PROCESS_PRIVATE

PTHREAD_PROCESS_SHARED

 

4-2.等待條件變量

與線程鎖協同工做,wait以前應確保線程鎖成功加鎖,

下述wait函數內部率先解鎖然後等待條件變化(掛起),函數返回前再次加鎖。

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,

                                            const struct timespec *restrict abstime);

使用流程:

/*------------------------------------------------------------*/

pthread_mutex_lock(&mutex);

pthread_cond_wait(&cond,&mutex);  //內部先解鎖,然後等條件,最後加鎖後返回

pthread_mutex_unlock(&mutex);

/*------------------------------------------------------------*/

 

4-3.喚醒條件掛起線程

當其餘線程完成工做釋放條件時,喚醒其餘線程

但條件變量是互斥使用,只可能有一個線程得到該條件控制權

int pthread_cond_signal(pthread_cond_t *cond);      //只喚醒其中一個線程

int pthread_cond_broadcast(pthread_cond_t *cond);   //可能會喚醒全部線程,產生驚羣現象



<<END>>

相關文章
相關標籤/搜索