mutex 线程访问控制
由于线程共享进程的资源和地址空间,因此在对这些资源进行操作时,必须考虑到线程间资源访问的唯一性问题。POSIX 中线程同步的方法主要有互斥锁和信号量。
mutex 是以一种简单的加锁方法来控制对共享资源的存取。这个互斥锁只有两种状态,也就是上锁和解锁,可以把互斥锁看做是某种意义上的全局变量。
在同一时刻只能有一个线程持有某个互斥锁,拥有该锁的线程能够对共享资源进行操作。若其他线程试图持有一个已经上锁来的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。这把互斥锁使得共享资源按序在各个线程中操作。
互斥锁主要包括以下几种操作:
1.互斥锁初始化: pthread_mutex_init。
2.互斥锁上锁:pthread_mutex_lock。
3.互斥锁判断上锁:pthread_mutex_trylock。如果对象被上锁,则返回EBUSY
4.互斥锁解锁:pthread_mutex_unlock。
5.删除互斥锁:pthread_mutex_destroy。
创建互斥锁有两种方式:静态和动态
静态:pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
PTHREAD_MUTEX_INITIALIZER是一个结构常量。
动态:使用pthread_mutex_init()来初始化互斥锁
函数格式:
头文件:
#include<pthread.h>
函数原型:
int pthread_mutex_init(pthread_mutex_t *mutex, //指向互斥锁对象的指针
const pthread_mutexattr_t *mutexattr)//互斥锁的属性
int pthread_mutex_lock(pthread_mutex_t *mutex) //指向互斥锁对象的指针
int pthread_mutex_trylock()(pthread_mutex_t *mutex) //指向互斥锁对象的指针
int pthread_mutex_unlock(pthread_mutex_t *mutex) //指向互斥锁对象的指针
int pthread_mutex_destroy(pthread_mutex_t *mutex) //指向互斥锁对象的指针
其中mutexattr:
PTHREAD_MUTEX_INITIALIZER:创建快速互斥锁。
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP:创建递归互斥锁。
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP:创建检错互斥锁。
mutexattr如果为 NULL 表示按默认属性创建互斥锁。
返回值:
成功:0
出错:-1
使用实例
在使用互斥锁前,需要定义互斥锁(全局变量),定义互斥锁对象形式为:
pthread_mutex_t mutex;
还可以用宏 PTHREAD_MUTEX_INITIALIZER 来初始化静态分配的互斥锁,如下:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
对于静态初始化的互斥锁,不需要调用 pthread_mutex_init() 函数。
使用默认初始化互斥锁:
pthread_muteattr_t mattr;
int retval;
pthread_mutex_init (&lock, NULL);
使用自定义属性初始化互斥锁:
ret = pthread_mutex_init (&lock, &mttr);
在使用互斥锁时,通常先使用 pthread_mutex_lock 上锁,然后执行需要原子操作的代码,最后再使用 pthread_mutex_unlock 解锁:
/* 互斥锁上锁 */
pthread_mutex_lock(&mutex);
/* 原子操作的代码 */
.....
/* 互斥锁解锁 */
pthread_mutex_unlock(&mutex);