公司网站模板免费源码下载,杭州电子商务公司排行,wordpress主题虚拟资源交易平台,网站找建站公司互斥量
数值只有0或1 谁获得互斥量#xff0c;就必须由谁释放同一个互斥量。 但其实在freeRTOS中#xff0c;任务A获取的互斥锁#xff0c;任务B也能释放。因此谁上锁谁开锁只是约定#xff0c;在程序实现上不是强制的。 “可重入的函数是指#xff1a;多个任务同时…互斥量
数值只有0或1 谁获得互斥量就必须由谁释放同一个互斥量。 但其实在freeRTOS中任务A获取的互斥锁任务B也能释放。因此谁上锁谁开锁只是约定在程序实现上不是强制的。 “可重入的函数是指多个任务同时调用它、任务和中断同时调用它函数的运行也是安全的。可重入的函数也被称为线程安全”(thread safe)。 每个任务都维持自己的栈、自己的CPU寄存器如果一个函数只使用局部变量那么它就是线程安全的。 函数中一旦使用了全局变量、静态变量、其他外设它就不是可重入的如果该函数正在被调用就必须阻止其他任务、中断再次调用它。 上述问题的解决方法是任务A访问这些全局变量、函数代码时独占它就是上个锁。这些全局变量、函数代码必须被独占地使用它们被称为临界资源。 互斥量的使用过程如下
互斥量初始值为1
任务A想访问临界资源先获得并占有互斥量然后开始访问
任务B也想访问临界资源也要先获得互斥量被别人占有了于是阻塞
任务A使用完毕释放互斥量任务B被唤醒、得到并占有互斥量然后开始访问临界资源
任务B使用完毕释放互斥量互斥量函数
使用互斥量需要定义
#define configUSE_MUTEXES 1创建
成功则返回句柄失败则返回NULL
SemaphoreHandle_t xSemaphoreCreateMutex( void ); // 动态分配
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer );
获取与释放
不能在中断中使用。除此之外与信号量相同
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );//删除
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );//释放
BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait);//获取
优先级反转问题
使用信号量时有时会出现低优先级先运行高优先级不运行的问题原因在于 低优先级的任务先创建先获取了信号量 不需要取信号量的中优先级任务第二个创建阻塞了低优先级任务此时低优先级任务信号量还没释放 高优先级任务后创建此时take信号量被阻塞无法运行 在FreeRTOS_信号量_学习笔记中修改三个任务的优先级 xTaskCreate(CarTask, car1, 128, g_cars[0], osPriorityNormal, NULL);xTaskCreate(Car2Task, car2, 128, g_cars[1], osPriorityNormal1, NULL);xTaskCreate(Car3Task, car3, 128, g_cars[2], osPriorityNormal2, NULL); 同时将第二辆车的任务中获取信号量和释放信号量的语句删除。此时CarTask被Car2Task阻塞Car3Task无法运行 此时只要将信号量替换为互斥量即可解决优先级反转问题。其原理是用了优先级继承功能。 假设持有互斥锁的是任务A如果更高优先级的任务B也尝试获得这个锁 任务B说你既然持有宝剑又不给我那就继承我的愿望吧 于是任务A就继承了任务B的优先级 这就叫优先级继承 等任务A释放互斥锁时它就恢复为原来的优先级 互斥锁内部就实现了优先级的提升、恢复
递归锁
互锁
A获得互斥量M1
B获得互斥量M2
A还想获得M2才能运行A阻塞
B还想获得M1才能运行B阻塞
AB都阻塞都无法释放其所持有的互斥量自锁
A获得了互斥量M
他调用了一个库函数库函数也想获取互斥量M
库函数阻塞A休眠无法释放互斥量解决以上问题可以使用递归锁其特性为
任务A获得递归锁M后它还可以多次去获得这个锁take了N次要giveN次这个锁才会被释放
递归锁的函数和一般互斥量的函数名不一样参数类型一样。
递归锁互斥量创建xSemaphoreCreateRecursiveMutexxSemaphoreCreateMutex获得xSemaphoreTakeRecursivexSemaphoreTake释放xSemaphoreGiveRecursivexSemaphoreGive
递归锁主要用于解决同一个线程多次获取同一个锁时的同步问题不涉及多个线程之间的并发访问。