1、信号量是啥:
μC/OS-II的编写者Jean在他的书中写道:信号量实际上是一种约定机制,在多任务内核中普遍使用;μC/OS-II中的信号量由16位的无符号整型的信号量计数器(0~65535)和由等待该信号量的任务组成的任务等待表两部分组成;它的职责是什么呢?有三种:
(1)控制共享资源的使用权;
(2)标志着某事件的发生;
(3)使两个任务的行为同步;
就如同一群病人等着看医生一样,任务就是病人,内核就是医生,医生在一个时间内只能处理一个病人,医生发出一张绿卡说谁拿到了绿卡就进来看病吧。那么信号量就相当于这张绿卡,任何一个任务要被运行,就需要先拿到信号量。其他没拿到信号量的任务只好“挂起”继续排队等,直到内核处理完当前任务(医生看完当前病人);
信号量的约定机制使用的位数(8位、16位、32位)决定了信号量的取值范围(2^8,2^16,2^32);当信号量只有两个值0和1的时候,就被称为二值信号量。信号量有效意味着必须大于0,为0 则无效;
对信号量的操作有三种:
(1)初始化(或叫建立):需要给信号量赋初值;
(2)等信号(或叫挂起):等待信号量的任务表必须清空;
(3)给信号(或叫发信号):任务以“发信号/给信号”来释放信号量;
如果没有任务等待信号量,那么信号量只需要简单地加1就好;如果有任务等待,那么下一个任务直接进入就绪状态,然后信号量不用加1;那么哪个任务获得信号量呢?很多内核的处理方法只有两种:
(1)按排队规矩来,即是FIFO, 先入先出,哪个病人先来就先就诊;
(2)等待任务中优先级最高的那个,就是说哪个病人最严重,最需要尽快治疗的;
然而需要注意的是: μC/OS-II这个医生很怪,只接受第二种,理由是它是可剥夺型内核:优先级高的先来!哪个病人病得不行了快挂了,那肯定得先让他先来。正在治疗中的病人(正在执行中的任务),不好意思,你先一边去等会(被挂起);等我处理完这个比你更高优先级的家伙再说。
在使用信号量之前,一定要就进行初始化,而且作为互斥条件,信号量必须初始化为1;
信号量使用事件控制块的成员OSEventCnt作为计数器,而用OSEvevtTbl[]数组来作为等待任务表。
2、什么时候该用信号量
Jean 在他的书中讲得很明确,尽管信号量比较好用,但是也不要对信号量过分使用,因为请求和释放信号量的过程也是要费蛮多时间的;比如,共享简单的变量只需要关、开中断就可以了,而没必要使用信号量。当开关中断都无法处理时候,就考虑用信号量,例如共享变量是浮点数,关中断时间过长会影响中断延迟时间,所以就应该用信号量。
文章评论(0条评论)
登录后参与讨论