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