1、概述編程
在《線程編程常見API簡介(上) 》中講述了有關線程建立過程當中經常使用的 API 的使用方法,本節繼續講述有關線程編程中經常使用 API 的使用方法。主要說明有關線程鎖、線程局部變量等 API 的使用。多線程
2、經常使用 API函數
1)線程鎖 APIspa
1.1)線程鎖的初始化及銷燬:pthread_mutex_init/pthread_mutex_destroy;在 acl 庫中對應的 API 爲:acl_pthread_mutex_init/acl_pthread_mutex_destroy。.net
/** * 初始化線程鎖對象 * @param mutex {pthread_mutex_t*} 線程鎖對象 * @param attr {const pthread_mutexattr_t*} 線程鎖屬性對象 * @return {int} 返回 0 表示成功,不然表示出錯 */ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); /** * 銷燬線程鎖資源 * @param mutex {pthread_mutex_t*} 線程鎖對象,以前必須成功調用了 * pthread_mutex_init 初始化了線程鎖對象 * @return {int} 返回 0 表示成功,不然表示出錯 */ int pthread_mutex_destroy(pthread_mutex_t *mutex);
在線程初始化 API 中有一個線程鎖屬性對象:pthread_mutexattr_t *attr,該對象須要調用以下函數進行初始化及銷燬:線程
1.2)線程鎖屬性對象的初始化及銷燬:pthread_mutexattr_init/pthread_mutexattr_destroy。code
/** * 初始化線程鎖屬性對象 * @param attr {pthread_mutexattr_t*} 線程鎖屬性對象 * @return {int} 返回 0 表示成功,不然表示出錯 */ int pthread_mutexattr_init(pthread_mutexattr_t *attr); /** * 銷燬在初始化線程鎖屬性對象時分配的內部資源 * @param attr {pthread_mutexattr_t*} 線程鎖屬性對象 * @return {int} 返回 0 表示成功,不然表示出錯 */ int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
除了上面所列出的初始化線程鎖的方法外,在LINUX下臺下還有一個快速對線程鎖進行初始化的方法,以下聲明線程鎖變量便可:對象
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1.3)線程鎖加鎖解鎖 API:pthread_mutex_lock/pthread_mutex_unlock;在 acl 庫中相應的表現形式爲:acl_pthread_mutex_lock/acl_pthread_mutex_unlock。blog
/** * 對線程鎖加鎖,一直至成功加鎖或出錯爲止 * @param mutex {pthread_mutex_t*} 線程鎖對象 * @return {int} 返回 0 表示成功加鎖,不然表示出錯 */ int pthread_mutex_lock(pthread_mutex_t *mutex); /** * 對加鎖的線程鎖解鎖 * @param mutex {pthread_mutex_t*} 線程鎖對象 * @return {int} 返回 0 表示成功解鎖,不然表示出錯,出錯緣由通常爲: * 線程鎖對象無效或當前該解鎖線程並未擁有該線程鎖 */ int pthread_mutex_unlock(pthread_mutex_t *mutex);
除了上面提到的阻塞式加鎖方法,還有一個非阻塞式的加鎖方法,調用 pthread_mutex_trylock API:資源
/** * 嘗試對線程鎖加鎖,若是該鎖未被其它線程擁有,則本加鎖線程便加鎖 * 成功,不然當即返回,並返回 EBUSY 表示該線程鎖正被其它線程擁有 * @param mutex {pthread_mutex_t*} 線程鎖對象 * @return {int} 返回 0 表示成功加鎖,不然返回未成功加鎖緣由,通常 * 緣由有:線程鎖對象無效,或該鎖正被其它線程加鎖 */ int pthread_mutex_trylock(pthread_mutex_t *mutex);
須要區分 pthread_mutex_lock 和 pthread_mutex_trylock 兩種不一樣加鎖方法,前者在成功加鎖前會一直阻塞到其它線程釋放鎖(或出錯了),後者則會當即返回,根據其返回值來檢查是否成功加鎖。
2)線程鎖示例
下面以一個例子來簡要說明一下上面線程鎖的一些 API 的使用方法:
#include <pthread.h> #include <assert.h> /* 全局靜態線程鎖 */ static pthread_mutex_t __mutex; /* 全局靜態變量 */ static int __count = 0; static void *thread_fn(void *arg) { (void) arg; /* 避免編譯器警告 */ /* 對線程鎖加鎖 */ assert(pthread_mutex_lock(&__mutex) == 0); __count++; /* 對全局靜態變量加 1 */ /* 對線程鎖解鎖 */ assert(pthread_mutex_unlock(&__mutex) == 0); return NULL; } int main(void) { int i; pthread_t tids[10]; /* 使用缺省的屬性初始化線程鎖 */ assert(pthread_mutex_init(&__mutex, NULL) == 0); /* 建立 10 個子線程 */ for (i = 0; i < 10; i++) assert(pthread_create(&tids[i], NULL, thread_fn, NULL) == 0); /* 等待全部子線程結束 */ for (i = 0; i < 10; i++) assert(pthread_join(&tids[i], NULL) == 0); /* 判斷全局靜態變量最後的結果應該爲 10 */ assert(__count == 10); /* 銷燬線程鎖 */ assert(pthread_mutex_destroy(&__mutex) == 0); return 0; }
3) 線程局部變量
有關線程局部變量的含義、API以及使用示例,請參考另外兩篇文章:《多線程開發時線程局部變量的使用》,《再談線程局部變量》。
好了,先說這些吧,下一節繼續描述有關線程條件變量相關的 API 使用說明。