互斥量
对互斥量的理解
二进制信号量的互斥,容易导致死锁。即一个任务锁住后继续运行,在运行过程中再次请求解锁,导致后续没解锁信息无法继续下去,造成死锁。
- 比喻: 我要有工作经验的(锁住直到有工作经验的来才给工作)
- 我要工作才能有工作经验(请求工作不成功,不运行不达到条件)
递归锁:类似于嵌套,锁中锁 。
对互斥量的常规使用
互斥量创建。与信号量一样的句柄创建,函数运行后,初始值为1,不需要手动赋值。代码展示了创建串口通信1互斥量的代码
1 | Semaphore_Handle_USART1 = xSemaphoreCreateMutex(); |
跟二进制信号量一样的赋值方法,give和take即可对锁进行操作。
但是二进制信号量的互斥锁会导致优先级反转,即高优先级任务在监测到互斥锁锁住时进入阻塞状态放弃CPU资源,低优先级的任务进行运行,如果低优先级的任务不放弃CPU资源,高优先级的任务便不能执行。为了解决这个问题,我们引入了互斥量优先级继承的功能。
优先级继承功能:
Mutex有着优先级继承的属性,在高优先级的任务获取锁失败以后,
会将该高优先级任务的优先级赋给上锁的任务运行,即上锁的任务继承了高优先级任务的优先级。
当低优先级的任务放弃CPU资源时,重新给回高优先级任务继续运行,低优先级任务不再抢占高优先级任务,避免了优先级反转。
互斥量的缺陷:
互斥量任何任务都可以对这个锁进行解锁,如果出现了其他任务强行解锁该锁就不能正常用了。这个使用引入递归锁。
递归锁
递归锁的创建
1 | Semaphore_Handle_USART1 = xSemaphoreCreateRecursiveMutex(); |
递归锁的读取和释放
1 | xSemaphoreTakeRecursive(Semaphore_Handle_USART1, portMAX_DELAY); |
递归锁的可嵌套性,在任务中得到了锁的使用权,那么在里面任然拥有该权限,可以嵌套上锁。
1 | void Task3Function(void * param) |
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1186703947@qq.com