Vtaskdelay任务阻塞深入了解
通过 delay
函数,任务将自己从就绪链表(Ready List) 移到了延时链表(Delay List / Blocked List),并立即释放了CPU资源,从而让调度器去运行其他就绪的任务。
详细解释
在RTOS(如FreeRTOS)中,任务通常有以下几种状态,并通过不同的链表进行管理:
运行态 (Running):任务正在CPU上执行。
就绪态 (Ready):任务已经准备好可以运行,但当前有更高优先级的任务正在运行。它在就绪链表中等待。
阻塞态 (Blocked):任务因为等待某个事件(如延时、信号量、消息队列等)而暂时无法运行。它在阻塞链表(或叫挂起链表、等待链表)中。
当你调用 vTaskDelay()
时,发生了什么?
这个过程可以分解为以下几步:
运行态 (Running)
|--[调用vTaskDelay()]--> 阻塞态 (Blocked, 在Delay List)
|--[延时到期]--> 就绪态 (Ready, 回到Ready List)
核心:任务确实主动离开了就绪队列,进入了另一个“等待”队列,并释放了CPU。只是这个“等待”队列的准确名称是阻塞链表,其具体类型是延时链表。
关键总结
动作 | 结果 |
---|---|
调用 vTaskDelay() | 任务主动放弃CPU,自我阻塞。 |
链表操作 | 从就绪链表 -> 延时链表。 |
状态变化 | 就绪态 (Ready) -> 阻塞态 (Blocked)。 |
CPU资源 | 立即释放,调度器选择下一个最高优先级的就绪任务运行。 |
恢复条件 | 指定的延时时间到期(由SysTick中断服务程序检查)。 |
恢复后 | 从延时链表 -> 就绪链表,阻塞态 -> 就绪态,等待调度器再次分配CPU。 |
因此,使用 delay
是任务间协作的一种非常高效的方式,它让低优先级的任务可以主动让出CPU,使得系统能够及时响应高优先级任务,从而充分利用CPU资源。