何为信号量
信号量是实现任务间通信的机制,用于任务同步或资源互斥访问,常见于出现资源竞争型的任务。
信号量分类
二值信号量
二值信号量用于同步或临界资源访问,没有优先级继承机制,偏向于同步功能。二值信号量可以看作只有一个消息的队列,这个队列只能为有值和无值两种情况。
当二值信号量用于同步功能时,信号量创建后为空,任务1获取信号量进入阻塞,任务2触发条件释放信号量,任务1获得信号量进入就绪态,实现任务同步。
计数信号量
如果二值信号量是长度为1的队列,那么计数信号量则是长度大于1的队列。计数信号量一般用于事件计数与资源管理,当某事件发生时,任务释放一个信号,计数值加1,当任务处理某事件时,任务取消该信号量,计数值减1,信号量的计数值表示还有多少个事件没有处理。
互斥信号量
互斥信号量是一种特殊的二值信号量,具有优先级继承机制,适用于任务间的资源互锁。
用作互斥操作时,互斥信号量创建时是有值的,任务需要先获取互斥信号量使信号为空,其他任务要访问时将进入阻塞无法访问,保证了临界资源的安全。
递归信号量
递归信号量可重复获取调用,任务获取几次递归信号量就要释放几次信号量。
二值信号量原理
在多任务环境中,二值信号量相当于事件触发标志,释放了任务等待事件触发的那段时间,使任务进入阻塞态等待二值信号量释放唤醒任务,在阻塞的这段时间内CPU可以处理其他任务,不需要浪费CPU死等事件触发。
计数信号量原理
计数信号量用于资源管理,允许多个任务获取信号量访问共享资源,同时多个任务访问同一资源也会有限定。
互斥信号量原理
互斥信号量具有优先级继承机制,当某一临界资源受互斥量保护时,一个低优先级的任务正在使用该临界资源,此时互斥量处于闭锁状态,如果此时高优先级的任务想要对该资源进行访问因申请不到互斥量而进入阻塞状态,系统会将持有该互斥量的任务的优先级临时提升到高优先级任务的级别。
互斥量运作机制
互斥量控制块
信号量控制块
信号量控制块与消息队列一样,属于同一个结构体。
信号量相关函数
函数 | 功能 |
---|---|
xSemaphoreCreateBinary() | 创建二值信号量 |
xSemaphoreCreateCounting() | 创建计数信号量 |
vSemaphoreDelete() | 删除信号量 |
xSemaphoreGive() | 在任务中释放信号 |
xSemaphoreGiveFromISR() | 在中断中释放信号 |
xSemaphoreTake() | 在任务中获取信号 |
xSemaphoreTakeFromISR() | 在中断中获取信号 |
xSemaphoreCreateMutex() | 创建互斥量 |
vSemaphoreDelete() | 删除互斥量 |
xSemaphoreTake() | 获取互斥量 |
xSemaphoreGive() | 释放互斥量 |