μCOS-Ⅱ操作系统中的PEND(阻塞zuse)和SUSPEND(挂起)和SLEEP(睡眠)三种状态

挂起是一种主动行为,因此恢复也应该要主动完成;

阻塞,睡眠则是一种被动行为,是在等待事件或资源时任务的表现;

睡眠是一种半主动半被动的行为,到了某个时间点,被要求去睡觉,到了下一个确定时间点,自己主动起来继续工作。

三者的表现方式都是    对应的任务优先级从任务就绪表中清除,只不过实现方式不一样。

在μCOS-Ⅱ操作系统中,两者分别对应以下几种情形: 
            1.使用OSTaskSuspend()函数将任务挂起,即任务进入挂起状态;
            2.使用OSTimeDly()和OSTimeDlyHMSM()函数将任务延时,即任务进入睡眠状态;
            3.使用OSSemPend()函数等待事件时,即任务进入阻塞状态;

上述情形实现的方式分别如下:
1. 任务可以挂起本身,也可以挂起别的任务。
任务可以挂起本身:
通过指定OS_PRIO_SELF来挂起调用本函数的任务本身,即OSTaskSuspend(OS_PRIO_SELF);
通过指定当前运行任务的优先级来挂起调用本函数的任务本身,即OSTaskSuspend(OSTCBCur->OSTCBPrio);
这种情况下就需要进行任务调度程序。
挂起别的任务,那就不需要进行任务调度程序,因为挂起的任务肯定是比正在运行的任务的优先级低。
不管该任务是否在任务就绪表中(要被挂起的任务可能不在就绪表中,原因是:该任务可能是在      等待延时的期满     或者     等待事件的发生),都将对应的任务从任务就绪状态表中移除出去,然后在OS_TCB的OSTCBStat变量设置为OS_STAT_SUSPEND标志了。

2. 调用OSTimeDly()或者OSTimeDlyHMSM()函数会使操作系统将当前任务从任务就绪状态表中移除出去,对该任务控制块中的OSTCBDly进行赋值,任务进入睡眠状态。然后进行一次任务调度,并执行下一个优先级最高的就绪态任务。

3. OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
该函数允许用户定义一个最长等待时间timeout,这样可以避免该任务无休止地等待下去。如果timeout是一个大于 0 的值,将timeout赋值给OSTCBDly,那么该任务将一直等到信号有效或者等待超时 时;如果该参数值为 0,该任务将一直等待下去,直到信号有效。
OS_TCB的OSTCBStat变量设置为OS_STAT_SEM标志了。
OSEventTaskWait()函数将当前任务从任务就绪状态表中移除出去,然后任务一直等待事件,即任务进入阻塞状态


从上述情形恢复到就绪状态的措施如下:
1. 被挂起的任务只有通过调用OSTaskResume()函数才能恢复,通过清除OSTCBStat域中的OS_STAT_SUSPEND位来取消挂起的。至于这个时候该任务是否处于就绪态还需要确认OSTCBDly是否为0以及该任务是否还处于等待事件触发的状态,判断程序如下:
((OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) & (OSTCBDly == 0)
其中OS_STAT_RDY = 0x00 OS_STAT_SEM = 0x01  OS_STAT_MBOX = 0x02  OS_STAT_Q = 0X04
OS_STAT_SUSPEND = 0x08   OS_STAT_MUTEX  =  0x10 OS_STAT_FLAG = 0x20
若是都满足的话,那么就将任务从挂起状态变成就绪状态,不满足后面延时期满和等待事件两条件的话,就将任务从挂起状态变成睡眠状态或阻塞状态。

2.规定的时间期满或者通过调用OSTimeDlyResume(prio)函数取消了延时;
通过调用该函数和指定任务的优先级来使延时的任务不等待延时的期满而直接处于就绪态。
通过赋予OSTCBDly  0值,若任务此时没有被挂起,则就进入就绪态。判断程序如下
(OSTCBStat &= OS_STAT_SUSPEND) == OS_STAT_RDY,
在这里不会有等待事件这种状态了,因为等待事件和任务延时两者只能依次发生,不会同时出现的。

3.通过调用OSSEMPost(OS_EVENT *pevent)函数,释放一个信号量
OSEventTaskRdy()函数将当前等待该信号的任务列表中的优先级最高的任务移除出去,并且赋予OSTCBDly  0值,然后判断该任务是否被挂起,若任务此时没有被挂起,则就进入就绪态。判断程序如下:
OSTCBStat == OS_STAT_RDY
在这里不会有任务延时这种状态了,因为等待事件和任务延时两者只能依次发生,不会同时出现的。

操作系统中挂起、睡眠、阻塞的区别形象解释
故事:
你控制了一个雇工为你干活。你对雇工的控制是通过编程来实现的。
挂起的意思就是你对主动对雇工说:“你睡觉去吧,用着你的时候我主动去叫你,然后接着干活”。
睡眠的意思就是你主动对雇工说:“你睡觉去吧,某时某刻过来报到,然后接着干活”。
阻塞的意思就是,你发现你的雇工不知道在什么时候没经过你允许,自己睡觉呢,但是你不能怪雇工,肯定你这个雇主没注意,本来你让雇工扫地,结果扫帚被偷了或被邻居家借去了,你又没让雇工继续干别的活,他就只好睡觉了。至于扫帚回来后,雇工会不会知道,会不会继续干活,你不用担心,雇工一旦发现扫帚回来了,他就会自己去干活的。因为雇工受过良好的培训。这个培训机构就是操作系统。


 

猜你喜欢

转载自blog.csdn.net/weixin_42900105/article/details/86231877