在操作系统中,任务挂起指将任务暂时停止执行 ,但任务相关资源仍保留,其状态被保存。
任务挂起和阻塞是操作系统中任务的两种不同状态,它们有以下区别:
引发原因
- 任务挂起:多由外部因素触发,像系统资源管理需求(如内存不足时,系统挂起部分任务 ),或是用户、系统管理员手动操作 。比如在调试程序时,手动挂起某个任务便于排查问题
- 任务阻塞:因任务自身等待某些条件发生导致,比如等待 I/O 操作完成(像等待从磁盘读取文件数据 )、等待信号量或互斥锁释放 。例如一个任务申请获取互斥锁,若锁被其他任务占用,该任务就会进入阻塞状态 。
对 CPU 资源占用情况
- 任务挂起:挂起的任务不占用 CPU 时间,不会参与 CPU 调度,直到被恢复才可能重新参与 。比如挂起一个后台数据处理任务,它就不会再占用 CPU 资源 。
- 任务阻塞:在一些系统中,阻塞的任务仍留在就绪队列,可能占用 CPU 时间(部分系统会将其从就绪队列移除 )。例如等待网络数据接收的任务,在等待期间可能仍在就绪队列中占用资源 。
恢复执行的方式
- 任务挂起:需外部显式调用恢复函数(如 FreeRTOS 里的
vTaskResume
)来恢复,系统资源状况变化或用户、管理员干预可触发恢复操作 。 - 任务阻塞:当所等待条件满足时自动恢复执行,如 I/O 操作完成、信号量被释放,阻塞任务就会进入就绪态等待调度 。
对系统资源占用
- 任务挂起:一般仍占用内存等系统资源(部分系统会将其换出到外存 )。
- 任务阻塞:处于内存中,持续占用内存资源 。
调度器处理方式
- 任务挂起:调度器直接忽略挂起状态的任务,不将其纳入调度范围 。
- 任务阻塞:调度器会关注阻塞任务,当阻塞条件解除,任务就有机会被调度执行 。
任务挂起函数
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
- xTaskToSuspend:待挂起任务的任务句柄,为NULL表示挂起任务自身。
- 需将宏INCLUDE_vTaskSuspend配置为 1。
任务恢复函数
void vTaskResume( TaskHandle_t xTaskToResume )
- INCLUDE_vTaskSuspend必须定义为 1。
- 不论任务被使用vTaskSuspend()挂起多少次,只需调用vTaskResume()一次,即可使其继续执行。被恢复的任务会重新进入就绪状态。
任务恢复函数(中断中恢复)
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
返回值如下:
- pdTRUE:任务恢复后需要进行任务切换。
- pdFALSE:任务恢复后不需要进行任务切换。
- 注意事项
- INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1。
- 在中断服务程序中调用 FreeRTOS 的 API 函数时,中断的优先级不能高于 FreeRTOS 所管理的最高任务优先级。
- 任务挂起注意事项:
- 不能从中断服务例程(ISR)中调用 ,若要在 ISR 中挂起任务,需使用
vTaskSuspendFromISR
。 - 避免死锁情况 ,如多个任务相互等待对方挂起的任务 ,可能导致死锁 。
- 注意优先级反转问题 ,即低优先级任务持有高优先级任务需要的资源 ,可采用优先级继承等策略解决 。
- 不能从中断服务例程(ISR)中调用 ,若要在 ISR 中挂起任务,需使用
本文所述内容为本人通过网络自学后归纳所得,仅服务于个人复习与学习需求,无任何商业应用意图。