读写锁

About 6 min

读写锁

基本概念

读写锁与互斥锁类似,可用来同步同一进程中的各个任务,但与互斥锁不同的是,其允许多个读操作并发重入,而写操作互斥。

相对于互斥锁的开锁或闭锁状态,读写锁有三种状态:读模式下的锁,写模式下的锁,无锁。

读写锁的使用规则:

  • 保护区无写模式下的锁,任何任务均可以为其增加读模式下的锁。
  • 保护区处于无锁状态下,才可增加写模式下的锁。

多任务环境下往往存在多个任务访问同一共享资源的应用场景,读模式下的锁以共享状态对保护区访问,而写模式下的锁可被用于对共享资源的保护从而实现独占式访问。

这种共享-独占的方式非常适合多任务中读数据频率远大于写数据频率的应用中,提高应用多任务并发度。

运行机制

相较于互斥锁,读写锁如何实现读模式下的锁及写模式下的锁来控制多任务的读写访问呢?

  • 若A任务首次获取了写模式下的锁,有其他任务来获取或尝试获取读模式下的锁,均无法再上锁。

  • 若A任务获取了读模式下的锁,当有任务来获取或尝试获取读模式下的锁时,读写锁计数均加一。

开发指导

接口说明

表 1 读写锁模块接口

功能分类

接口名称

描述

读写锁的创建和删除

LOS_RwlockInit

创建读写锁

LOS_RwlockDestroy

删除指定的读写锁

读模式下的锁的申请

LOS_RwlockRdLock

申请指定的读模式下的锁

LOS_RwlockTryRdLock

尝试申请指定的读模式下的锁

写模式下的锁的申请

LOS_RwlockWrLock

申请指定的写模式下的锁

LOS_RwlockTryWrLock

尝试申请指定的写模式下的锁

读写锁的释放

LOS_RwlockUnLock

释放指定读写锁

读写锁有效性判断

LOS_RwlockIsValid

判断读写锁有效性

开发流程

读写锁典型场景的开发流程:

  1. 创建读写锁LOS_RwlockInit。

  2. 申请读模式下的锁LOS_RwlockRdLock或写模式下的锁LOS_RwlockWrLock。

申请读模式下的锁:

  • 若无人持有锁,读任务可获得锁。
  • 若有人持有锁,读任务可获得锁,读取顺序按照任务优先级。
  • 若有人(非自己)持有写模式下的锁,则当前任务无法获得锁,直到写模式下的锁释放。

申请写模式下的锁:

  • 若该锁当前没有任务持有,或者持有该读模式下的锁的任务和申请该锁的任务为同一个任务,则申请成功,可立即获得写模式下的锁。
  • 若该锁当前已经存在读模式下的锁,且读取任务优先级较高,则当前任务挂起,直到读模式下的锁释放。

3.申请读模式下的锁和写模式下的锁均有三种:无阻塞模式、永久阻塞模式、定时阻塞模式,区别在于挂起任务的时间。

4.释放读写锁LOS_RwlockUnLock。

  • 如果有任务阻塞于指定读写锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度;

  • 如果没有任务阻塞于指定读写锁,则读写锁释放成功。

  1. 删除读写锁LOS_RwlockDestroy。

说明:

  • 读写锁不能在中断服务程序中使用。
  • LiteOS-A内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得读写锁之后,应该尽快释放该锁。
  • 持有读写锁的过程中,不得再调用LOS_TaskPriSet等接口更改持有读写锁任务的优先级