目录
前言
本专栏主要分享linux下并发编程相关知识,包括多进程,多线程,进程/线程间通信,并发同步控制,以及高并发下性能提升,请大家多多留言。
概念介绍
与前面介绍的互斥量,信号量类似,用于多线程/进程间同步控制,但与它们的不同之处在于,读写锁可以区分读加锁和写加锁,也就是说一把锁有两种不同的加锁方式,那么对于两种加锁方式下的并发控制也是不同。
这个不同点,也就是读写锁的精妙的所在。
应用场景
读写锁,有两种加锁方式:
(1)加读锁,也就是共享锁,多个并发可以同步加此种锁,同时可以访问临界区。
(2)加写锁,也就是独占锁,只有一个并发可以成功的加写锁,此时其它并发既不能加写锁,也不能加读锁,这就是独占的意义。
如下图所示:
基于rwlock的这个特点,在大并发中,读取临界区任务数量远远大于写临界区数量时,对于读任务只加共享读锁即可,比互斥量/信号量的性能会远远超过。
比如在系统中的用户信息,在每个并发登陆时都会访问,但它们大多数是只读,这样就可以共享访问,只对于少数注册/修改加写锁,此时互斥访问即可。
接口说明
头文件
rwlock定义
当然定义了还不能用,此时状态未知,必须初始化后才能用。
初始化/销毁
-
两种初始化方式
一种调用初始化接口,可以对rwlock的属性进行自定义设置,如果attr=NULL时,也会采用默认行为初始化;
另一种采用静态初始化,此时采用的都是默认属性
默认初始化成功返回0,错误时查看errno,成功后状态为未加锁。
-
rwlock资源进行销毁
当然销毁的只是变量对应的资源,变量还可以再初始化;
-
常见错误
几种未定义的行为,尽量避免踩坑:
(1)对还在加锁状态的rwlock进行销毁,行为没有定义,未知;
(2)对未初始化的rwlock进行销毁;
(3)多次初始化rwlock,可能会引起未知行为;
属性设置
-
属性初始化/销毁
头文件为
定义rwlock属性变量
初始化属性变量
销毁属性变量资源
-
共享属性
头文件为
获取和设置属性接口
默认初始化时,共享属性为PTHREAD_PROCESS_PRIVATE,也就是只能在单个进程间的多线程间使用。
如果要在多个进程间的线程间使用,就需要将属性设置为PTHREAD_PROCESS_SHARED,也就是能访问rwlock变量内存的线程都可以使用,进行并发控制。
阻塞式加锁
加读锁,如果其它任务已经加了写锁,此时会阻塞等待
加写锁,如果其它任务已经加了读/写锁,此时会阻塞等待
释放锁,不论是读锁还是写锁,都调用统一释放接口
非阻塞加锁
尝试加读锁,成功则返回0,如果其它任务已经加了写锁,此时会返回失败,不会阻塞
尝试加写锁,成功则返回0,如果其它任务已经加了写/读锁,此时会返回失败,不会阻塞
错误码有:
编程示例
启动3个进程,定义1个rwlock,其中第一个进程是写锁处理,后面进程是读锁处理;
代码工程hatchCode
代码位于gitcode,请大家关注,后面会持续更新到此仓库。
结尾
注:未经同意,不得转载!