外观
任务从创建到运行会经历哪些状态
约 1296 字大约 4 分钟
2026-11-10
在初学RTOS的时候,我们会发现很多资料里,都会写关于“任务状态”的内容,并且会给出一张状态切换图。
例如,在RT-Thread的官方文档中,给出了这样一张图。

在这篇文章中,我就来聊一聊为什么会有这样的状态图,以及这些状态倒底是什么?
为什么需要状态
任务为什么需要各种状态呢?
我们知道:任务并不总是需要持续不断地“努力”工作,而是会不断地调用RTOS提供的API接口,实现延时、等待事件等功能。
比如,当调用延时函数时,任务需要等待一段时间才能继续运行; 当调用获取信号量的接口,如果信号量暂时不可用,任务就必须一直等待直至被其他任务唤醒。
在这些情况下,任务暂时无法继续运行,但是原因又各不相同。为了把这些情况区分开来以方便管理,RTOS就需要给每个任务做一个标记,记录它当前处于什么样的状态。
有了这个状态标记,RTOS才能判断:哪些任务现在可以运行、哪些任务在等什么、又该在什么时候把它们唤醒。
任务的状态划分
不同RTOS对状态的划分和命名略有差别,但最核心的几个状态是相通的。
下面给出了一个简要的图示:

以上几个状态分别说明如下:
- 就绪态:处于就绪态的任务已经万事俱备,等待调度器分配CPU给它运行。
- 运行态:任务正在占用CPU执行任务函数。在单核CPU上,任何时刻有且只有一个任务处于运行态。
- 阻塞态:任务因为要等待某个事件而暂时无法继续,比如调用了延时、等信号量等。
- 挂起态:任务被显式地暂停,即使它本来可以运行,调度器也不会理会它,直到其他任务将它恢复。
在理解了几个状态后,我们可以看下状态之间的变迁:
- 创建 → 就绪:当调用创建任务的接口时,RTOS会分配任务控制块和栈、初始化好任务的入口和运行环境,然后把任务放进就绪队列。
- 就绪 → 运行:当轮到任务运行时,RTOS从就绪队列里选出该任务,把CPU的执行权交给它,任务这才真正开始执行,进入运行态。
- 运行 → 就绪:如果当前任务的时间片用完,RTOS将CPU执行权让给同优先级的其他任务;此外,任务也可能被更高优先级任务抢占,回到就绪态。
- 运行 → 阻塞:当任务调用延时函数,或者获取一个暂时不可用的信号量、消息队列时,任务从就绪队列移出,挂到对应的延时队列或等待队列上,进入阻塞状态。
- 阻塞 → 就绪:当延时时间到,或者别的任务释放了信号量、写入了消息,等待中的任务会被唤醒,重新回到就绪队列,进入就绪态。
- 运行/就绪 → 挂起:当想主动让某个任务暂停一段时间时,可以调用挂起接口,强制任务不参与调度。
- 挂起 → 就绪:当调用恢复接口时,被挂起的任务重新回到就绪态,等待调度器安排。
- 运行 → 结束:当任务函数返回,或者被删除时,任务占用的资源被回收,结束其存在。
总结
综上所述,任务状态并不是什么抽象的概念,而是用于标记任务当前处境的一种机制。
在整个任务的生命周期中,任务状态在就绪、运行、阻塞、挂起这几个状态之间来回切换。调用不同的接口,任务就进入不同的状态;调度器将根据这些状态,决定CPU在每一个时刻究竟交给谁。
理解这些状态的含义以及状态变迁,有助于我们理解任务为什么暂停运行、为什么会被抢占,从而更好地应用RTOS。
如果你希望系统地学习RTOS底层原理,可以了解我的《RTOS开发与实战》课程。
课程不是简单地讲解FreeRTOS API的使用,而是带你从零开始编写一个RTOS内核,逐步实现任务管理、任务调度、上下文切换、同步与通信等核心机制,并通过一个远程温湿度监控设备项目,将操作系统原理应用到实际嵌入式开发中。
适合希望深入理解RTOS工作原理、提升嵌入式底层开发能力的同学。
