概述
线程之间的需要访问一些共享资源,为了保证对共享资源的有序访问,防止竞争,需要对共享资源进行某种方式的保护,使得共享资源有序访问,线程互斥锁就是用来实现线程间互斥的一种手段。
typedef union
{
struct __pthread_mutex_s __data ;
char __size [ __SIZEOF_PTHREAD_MUTEX_T ];
long int __align ;
} pthread_mutex_t ; //互斥锁结构
线程互斥锁是存在于进程地址空间内部的一种保护机制,"类似于信号量",只不过存在于进程内部的地址空间(默认),在 POSIX 多线程中,使用类型 pthread_mutex_t 来描述一个线程互斥锁,例如:
pthread_mutex_t mutex;//定义一个锁
对线程互斥锁的操作如下:
1.初始化线程互斥锁(pthread_mutex_init )
2.P/V 操作(pthread_mutex_lock/ pthread_mutex_unlock )
3.销毁线程互斥锁(pthread_mutex_destory )
在 linux 系统中默认是没有 POSIX 手册的,所以很多函数不在 man 手册中,通过 man 命令可能会找不到,可以通过下面命令下载
sudo apt-get install manpages-posix-dev
初始化线程互斥锁
动态初始化线程互斥锁(pthread_mutex_init)
头文件:
函数原型:
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
作用:
初始化线程互斥锁 mutex
参数含义:
mutex:要初始化的线程互斥锁
attr:表示要设置的线程互斥锁的属性,为 NULL 表示使用默认属性
返回值:
成功返回 0
失败返回非 0,errno 被设置
静态初始化线程互斥锁
静态初始化线程互斥锁不需要使用函数 api 去对互斥锁进行操作,而是直接给互斥锁赋值 PTHREAD_MUTEX_INITIALIZER,如下:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER ;
就完成了对互斥锁的初始化工作。
两者的区别在于:
使用动态的方式进行初始化是在堆上创建的,在不使用了的时候要进行释放,而使用静态的方式进行初始化是存储在静态存储区的,在不使用的时候不用就行了。
销毁线程互斥锁(pthread_mutex_destory)
头文件:
函数原型:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
作用:
销毁线程互斥锁 mutex
参数含义:
mutex:要销毁的线程互斥锁
返回值:
成功返回 0
失败返回非 0,errno 被设置
上锁操作(获取锁操作)
阻塞等待获取锁(pthread_mutex_lock)
函数原型:
int pthread_mutex_lock(pthread_mutex_t *mutex);
作用:
获取线程互斥锁 mutex 并上锁,没获取到则阻塞
参数含义:
mutex:要获取的线程互斥锁
返回值:
成功返回 0,表示已经获取了该线程互斥锁,可以进入临界区执行代码
失败返回-1,表示出错了,没有获取到锁
不出错也没有返回则“阻塞”,表示正在等待该锁释放
非阻塞等待获取锁(pthread_mutex_trylock)
头文件:
函数原型:
int pthread_mutex_trylock(pthread_mutex_t *mutex);
作用:
获取线程互斥锁 mutex 并上锁 , 没获取到则立即返回
参数含义:
mutex:要获取的线程互斥锁
返回值:
成功返回 0,表示已经获取了该线程互斥锁,可以进入临界区执行代码
失败返回其他值
限时等待获取锁(pthread_mutex_timedlock)
函数原型:
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
作用:
获取线程互斥锁 mutex 并上锁 , 会等待 abstime 秒,如果超过这个时间则直接返回
参数含义:
mutex:要获取的线程互斥锁
abstime:是一个绝对时间(当前时间+等待时间),表示超过这个时间将直接返回
返回值:
成功返回 0,表示已经获取了该线程互斥锁,可以进入临界区执行代码
失败返回错误码
解锁操作(pthread_mutex_unlock)
头文件:
函数原型:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
作用:
获取线程互斥锁 mutex 并解锁
参数含义:
mutex:要解锁的线程互斥锁
返回值:
成功返回 0,
失败返回错误码
线程属性
就像线程具有属性一样,用于线程互斥的互斥量的也有相应的属性,互斥量属性的数据类型是用 pthread_mutexattr_t 结构来表示的,在使用互斥量前必须初始化。
typedef union
{
char __size [ __SIZEOF_PTHREAD_MUTEXATTR_T ];
int __align ;
} pthread_mutexattr_t ;
初始化线程互斥锁属性(pthread_mutexattr_init)
头文件:
函数原型:
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
作用:
初始化线程互斥锁的属性 attr
参数含义:
attr:线程互斥锁属性
返回值:
成功返回 0,
失败返回错误码
销毁线程互斥锁属性(pthread_mutexattr_destory)
头文件:
函数原型:
int pthread_mutexattr_destory(pthread_mutexattr_t *attr);
作用:
销毁线程互斥锁的属性 attr
参数含义:
attr:线程互斥锁属性
返回值:
成功返回 0,
失败返回错误码
获取线程互斥锁属性(pthread_mutexattr_getpshared)
头文件:
函数原型:
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared);
作用:
获取线程互斥锁的属性 attr 的值放入 pshared 中
参数含义:
attr:线程互斥锁属性
pshared: 保存获取到的线程属性
返回值:
成功返回 0,
失败返回错误码
备注:
获取的属性有两种情况:
PTHREAD_PROCESS_PRIVATE 这种是默认情况,表示互斥锁只能在本进程中使用
PTHREAD_PROCESS_SHARED 表示互斥锁可以在不同进程间使用
enum
{
PTHREAD_PROCESS_PRIVATE ,
#define PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
PTHREAD_PROCESS_SHARED
#define PTHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
};
设置线程互斥锁属性(pthread_mutexattr_setpshared)
头文件:
函数原型:
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,int pshared);
作用:
设置线程互斥锁的属性 attr 为值 pshared
参数含义:
attr:线程互斥锁属性
pshared:要设置的线程属性,为 PTHREAD_PROCESS_PRIVATE 表示互斥锁只能在本进程中使用,为 PTHREAD_PROCESS_SHARED 表示互斥锁可以在不同进程间使用
返回值:
成功返回 0,
失败返回错误码