一、概述
在《线程编程常见API简介(上) 》中讲述了有关线程创建过程中常用的 API 的使用方法,本节继续讲述有关线程编程中常用 API 的使用方法。主要说明有关线程锁、线程局部变量等 API 的使用。
二、常用 API
1)线程锁 API
1.1)线程锁的初始化及销毁:pthread_mutex_init/pthread_mutex_destroy;在 acl 库中对应的 API 为:acl_pthread_mutex_init/acl_pthread_mutex_destroy。
/** * 初始化线程锁对象 * @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。
/** * 初始化线程锁属性对象 * @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。
/** * 对线程锁加锁,一直至成功加锁或出错为止 * @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 使用说明。
个人微博:http://weibo.com/zsxxsz
本文地址:http://zsxxsz.iteye.com/blog/1567814
acl 库下载:https://sourceforge.net/projects/acl/