请选择 进入手机版 | 继续访问电脑版
查看: 96|回复: 0

[技术交流] Alios Things之信号量

[复制链接]

13

主题

34

帖子

140

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
140
发表于 2019-11-1 14:59:18 | 显示全部楼层 |阅读模式
1、前言
为了避免软件访问共享资源时互相影响甚至冲突,一般在保护共享资源时,有以下几种处理方式:开关中断、信号量、互斥量、锁。
多任务可以通过获取信号量来获取访问共享资源的门禁,可以配置信号量数目,让多个任务同时获取门禁。当信号量无法获取时,相关任务会通过优先级排序来等待信号量释放,并让出CPU资源;其缺点是存在高低任务优先级反转问题。
2、信号量与任务状态关系
当调用krhino_sem_take()时,若信号量已被占用,任务将由RDY状态进入PEND状态;krhino_sem_take/give超时情况下,任务将由PEND状态进入RDY状态。当任务为PEND状态时,若有其他任务调用krhino_task_suspend(),任务将由PEND状态进入PEND_SUSPEND状态;当任务为PEND_SUSPEND时,若有其他任务调用krhino_task_resume(),任务将由PEND_SUSPEND状态进入PEND状态。
3、信号量的操作
①静态创建
k_start_t krhino_sem_create(ksem_t sem, const name_t name, sem_count_t count)
sem占用的内存由使用者直接传入,不在内部申请内存。
②动态创建
k_start_t krhino_sem_dyn_create(ksem_t **sem, const name_t *name, sem_count_t count)
sem占用的内存在创建接口内部通过krhino_mm_alloc申请。
③静态删除
k_start_t krhino_sem_del(ksem_t sem, const name_t name, sem_count_t count)
④动态删除
k_start_t krhino_sem_dyn_create(ksem_t **sem, const name_t *name, sem_count_t count)
两者的区别在于动态删除需要释放sem占用的内存,其他的处理并无差异。
4、信号量的获取与释放
①sem获取
k_start_t krhino_sem_take(ksem_t *sem, tick_t ticks)
信号量获取分为以下四种情况:
成功获取:信号量的count计数大于0,表示未完全占用,返回take信号量成功。
非等待获取:ticks设置为RHINO_NO_WAIT,表明当前如果无法获取信号量,直接返回错误RHINO_PEND_WAIT。
设置最大等待时间:ticks设置为非0、非全F有效值,当前任务会被加入tick的延时队列,当达到延时时间后,如果任务还被阻塞,返回超时RHINO_BLK_TIMEOUT。
无限等待:ticks设置为全F,则该任务会永久等待此信号量。除非使用信号量删除接口krhino_sem_del,或者强制任务调度接口krhino_task_wait_abort。
②sem释放
释放接口包括唤醒单个任务和唤醒多个任务:
kstart_t krhino_sem_give(ksem_t sem)
kstart_t krhino_sem_give_all(ksem_t
sem)
krhino_sem_give只会将当前阻塞在此信号量的最高优先级任务恢复;
krhino_sem_give_all会将阻塞在此信号量的所有任务恢复。
恢复过程分为以下几个步骤:
如果当前信号量没有任务阻塞,则信号量count++,并返回成功;
否则唤醒单个或多个优先级任务;
将唤醒任务从tick延时队列中删除。
4、使用注意事项
中断禁止信号量获取检测
信号量的获取接口在中断上下文调用时很容易发生死锁问题。当被打断的上下文和打断的中断上下文要获取同一个信号量时,会发生互相等待的情况。本内核会在take信号量时进行检测,如果是中断上下文,则直接返回失败。
占用信号量非等待、永远等待、延时使用的区别
krhino_sem_take传入延时ticks为0,获取不到信号量会立即报失败;ticks为全F时,会永远在此等待,直到获取到信号量,可能会造成该任务无法继续进行;其他值标识有最大延时上限,达到上限时,即使未获取到信号量,tick中断处理也会将任务唤醒,并返回状态为超时。
信号量优先级反转问题
当高优先级的任务需要的信号量被低优先级任务占用时,CPU资源会调度给低优先级的任务。此时,如果低优先级任务需要获取的另一个信号量被中优先级的PEND任务所占用,那么低优先级的任务就需要等待中优先级的任务事件到来,并释放信号量,就出现了高中优先级任务并不是等待同一个信号量,导致中优先级任务先运行的现象。
该优先级反转缺陷,在互斥机制中得以解决,其途径在于动态提高低任务运行优先级来避免任务优先级的反转问题。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表