进程的就绪、执行、阻塞和挂起

文章详细描述了进程从创建到终止的生命周期中,如何在不同状态下管理和分配CPU、资源A和资源B。重点讲解了进程在就绪、执行、阻塞、挂起等状态之间的转换及其资源变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        假设我们有一个进程, 它需要的资源有CPU, 资源A(在进程创建时为其分配), 资源B(进程运行时才发现需要资源B), 现在用这个进程来分析一下进程的几种状态. 先看图: 

图1: 进程的几种状态

1. 创建 --> 就绪(+资源A):

        操作系统为进程分配资源A, 进程进入就绪态, 等待CPU.

        进程当前拥有资源: 资源A

2. 就绪 --> 执行(+CPU):

        操作系统进行CPU的调度, 将CPU分配给该进程, 进程进入执行态. 

        进程当前拥有资源: CPU + 资源A

3. 执行 --> 就绪(-CPU): 

        操作系统进行CPU的调度, 剥夺该进程的CPU, 剥夺CPU的原因可能是该进程的时间片完或者是更高优先级的进程进入就绪态并抢占了CPU, 该进程进入就绪态. 

        进程当前拥有资源: 资源A

4. 执行 --> 阻塞(wait资源B, -CPU): 

        进程执行过程中发现需要资源B, 但资源B当前无法使用, 需要等待, 则进程进入阻塞态. 同时操作系统剥夺进程的CPU资源. 

        进程当前拥有资源: 资源A

5. 阻塞 --> 就绪(+资源B): 

        进程需要的资源B可以使用了, 操作系统将资源B分配给进程, 进程进入就绪态. 

        进程当前拥有资源: 资源A + 资源B

6. 阻塞 --> 挂起阻塞(-资源A): 

        如果资源B迟迟不能使用, 则进入阻塞态的进程将长期占有资源A, 这也是资源的浪费, 因此我们引入挂起, 把资源A让出来, 供其他进程使用. 操作系统剥夺资源A, 进程进入挂起阻塞态. 

        进程当前拥有资源:

7. 挂起阻塞 --> 阻塞(+资源A): 

        操作系统发现资源B快准备好了, 就马上归还抢占的资源A, 唤醒(激活)进程, 进程进入阻塞态. 

        进程当前拥有资源: 资源A

8. 挂起阻塞 --> 挂起就绪(+资源B): 

        资源B准备好了, 但是资源A暂时无法归还, 进程进入挂起就绪态. 

        进程当前拥有资源: 资源B

9. 挂起就绪 --> 就绪(+资源A): 

        资源A可以归还了, 操作系统归还资源A, 进程进入就绪态. 

         进程当前拥有资源: 资源A + 资源B

10. 就绪 --> 挂起就绪(-资源A): 

        进程刚被创建后, 分配了资源A, 进入就绪态, 如果操作系统发现CPU需要较长时间才会分配给该进程, 则为了资源A不被闲置, 就剥夺资源A, 进程进入挂起就绪态. 

        进程当前拥有资源:

11. 创建 --> 挂起就绪(没有分配资源): 

        操作系统创建了进程, 但是发现这个进程很久之后才能分配到CPU, 因此索性不给这个进程分配资源, 直接让进程进入挂起就绪态. 

        进程当前拥有资源:

12. 执行 --> 挂起就绪(-CPU, -资源A): 

        操作系统负担较大, 认为这个进程不重要, 为了减轻负担, 剥夺这个进程的资源, 进程进入挂起就绪态. 

        进程当前拥有资源:

13. 执行 --> 终止(-CPU, -资源A): 

        进程执行完毕, 释放资源, 进入终止态. 

<think>好的,我现在需要回答用户关于FreeRTOS中阻塞(Blocked)就绪(Ready)状态的区别的问题。首先,我要确保自己对这两个概念有准确的理解,然后组织一个清晰、易于理解的解释。 首先,回顾FreeRTOS的任务状态。FreeRTOS中的任务通常有几种状态:运行(Running)、就绪(Ready)、阻塞(Blocked)、挂起(Suspended)删除(Deleted)。用户问的是阻塞就绪区别,所以需要集中在这两个状态上。 阻塞状态是指任务在等待某个事件或资源时暂时停止执行。例如,任务可能调用vTaskDelay()进入阻塞状态,等待一段时间,或者等待信号量、队列消息等。在阻塞期间,任务不会占用CPU资源,直到等待的条件满足,任务才会转移到就绪状态,等待调度器分配CPU。 就绪状态是指任务已经准备好运行,但当前没有在执行,因为可能有更高优先级的任务正在运行,或者调度器尚未切换到它。处于就绪状态的任务在就绪列表中排队,等待调度器根据优先级选择执行。 接下来需要明确两者的主要区别:触发条件、资源占用、状态转换的条件以及应用场景。例如,阻塞状态是因为任务需要等待外部事件,而就绪状态是任务已经具备运行条件但未被调度。在资源占用方面,阻塞状态的任务不参与调度,而就绪状态的任务随时可能被调度执行。 可能还需要举例说明,比如任务A调用vTaskDelay(100)进入阻塞状态,此时任务B进入就绪状态,当时间到达后任务A回到就绪状态,而任务B可能正在运行或被更高优先级任务抢占。 另外,需要注意FreeRTOS的调度机制,比如基于优先级的抢占式调度,如何影响任务从就绪到运行的转换。同时,解释状态转换图可能会有帮助,但用户可能只需要文字描述。 需要避免过于技术化的术语,用通俗的语言解释,同时保持准确性。还要检查是否有常见的误解,比如阻塞状态的任务是否仍然占用某些资源,或者就绪状态的任务是否在等待其他条件。 最后,确保回答结构清晰,分点说明区别,可能用比较表格或分点对比,帮助用户一目了然。同时,结合应用场景,让用户明白何时任务会处于这两种状态,以及开发者应如何合理设计任务状态转换。</think>### FreeRTOS任务状态:阻塞 vs 就绪 深度解析 #### 一、核心区别对照表 | **特征** | **阻塞状态 (Blocked)** | **就绪状态 (Ready)** | |-----------------|-------------------------------------|----------------------------------| | **触发条件** | 主动等待事件/资源 | 具备运行条件 | | **CPU占用** | 0% | 0%(等待调度) | | **状态列表** | 阻塞列表(按等待条件组织) | 就绪列表(按优先级排序) | | **状态转换** | 事件触发 → 就绪 | 被调度选中 → 运行 | | **典型场景** | 延时、等待信号量/队列/通知 | 等待CPU时间片 | #### 二、阻塞状态详解(深度休眠模式) **▌ 进入条件:** ```c xTaskDelay(100); // 时间阻塞 xQueueReceive(queue, &data, portMAX_DELAY); // 队列阻塞 xSemaphoreTake(semaphore, portMAX_DELAY); // 信号量阻塞 ``` **▌ 内核机制:** - 任务从就绪列表转移到**阻塞列表** - 维护多个阻塞队列(按事件类型分类) - 使用**事件标志组**实现多条件等待: ```c xEventGroupWaitBits(eg, BIT_0 | BIT_1, pdTRUE, pdTRUE, portMAX_DELAY); ``` **▌ 唤醒过程:** ```mermaid graph LR A[阻塞任务] -->|事件发生| B[转移至就绪列表] B --> C{优先级检查} C -->|高于当前任务| D[触发上下文切换] C -->|低于当前任务| E[维持当前运行] ``` #### 三、就绪状态运作原理(候场准备模式) **▌ 列表管理策略:** - 每个优先级维护独立就绪列表 - 最高优先级非空列表头部任务获得CPU - 示例优先级分布: ``` 优先级5: [TaskA → TaskB → TaskC] ← 当前运行TaskA 优先级4: [空] 优先级3: [TaskD] ``` **▌ 抢占式调度示例:** ```c // 高优先级任务就绪时立即抢占 void highPriorityTask(void *pv) { while(1) { printf("High!"); // 输出后立即让出CPU vTaskDelay(1); } } void lowPriorityTask(void *pv) { while(1) { printf("Low..."); // 仅在无高优先级任务时执行 vTaskDelay(1); } } ``` #### 四、典型场景对比分析 **场景1:传感器数据采集** ```c void sensorTask(void *pv) { while(1) { // 阻塞等待采样完成信号 xSemaphoreTake(adcReadySemaphore, portMAX_DELAY); readSensorData(); // 进入就绪状态 processData(); // 可能需要多次调度 } } ``` - 采样期间:阻塞状态(不消耗CPU) - 数据处理时:就绪↔运行交替 **场景2:实时控制任务** ```c void motorCtrlTask(void *pv) { TickType_t xLastWakeTime = xTaskGetTickCount(); while(1) { updatePID(); // 固定周期执行 vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10)); } } ``` - 延迟期间:精确计时阻塞 - 执行时段:立即进入就绪状态(高优先级保证及时运行) #### 五、开发者注意事项 1. **阻塞超时设置**: ```c // 避免永久阻塞导致死锁 if(xQueueReceive(queue, &data, pdMS_TO_TICKS(100)) == errQUEUE_EMPTY) { // 超时处理逻辑 } ``` 2. **优先级反转预防**: - 使用优先级继承协议: ```c SemaphoreHandle_t mutex = xSemaphoreCreateMutex(); xSemaphoreCreateMutexStatic(&mutex); ``` 3. **状态监控技巧**: - 通过`uxTaskGetSystemState()`获取任务状态快照 - 使用Tracealyzer可视化工具分析状态迁移 **性能优化建议**: 对频繁切换的任务,合理设置`configTICK_RATE_HZ`(典型值100-1000Hz),平衡响应速度调度开销。高优先级任务应尽量减少阻塞时间,低优先级任务可适当延长阻塞周期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值