当前位置: 首页 > news >正文

set_current_state()和schedule()

schedule()set_current_state()结合使用的场景与逻辑,这是 Linux 内核中进程主动休眠的核心组合,二者配合实现了 “进程主动放弃 CPU 并进入休眠状态,等待特定事件唤醒” 的核心功能,也是驱动、内核同步机制中最常用的休眠方式。

首先明确核心逻辑:set_current_state()负责设置当前进程的休眠状态(标记进程为非运行态),schedule()负责放弃 CPU 并触发调度,二者必须配合使用,否则会出现 “伪休眠” 或进程无法被正常唤醒的问题。

两个函数的核心配合逻辑

1. 为什么必须配合使用?
  • 单独调用schedule():进程只是暂时让出 CPU,仍处于TASK_RUNNING状态,会被pick_next_task()重新挑选,很快又会获得 CPU 执行权,无法实现 “长期休眠等待事件”。
  • 单独调用set_current_state():仅修改了进程状态,进程仍持有 CPU 执行权,不会主动放弃,直到时间片耗尽被抢占,且休眠状态无法生效。
  • 配合使用:set_current_state()先将进程标记为休眠状态(非TASK_RUNNING),再调用schedule()放弃 CPU 并触发调度,此时进程会被从运行队列中移除,不再被调度器挑选,直到被wake_up_process()等函数唤醒并恢复为TASK_RUNNING状态。
2. 核心配合流程(主动休眠的标准步骤)
  1. 前置准备:确保进程运行在进程上下文,且未持有自旋锁(自旋锁不允许休眠)。
  2. 设置休眠状态:调用set_current_state(),将当前进程状态设为TASK_INTERRUPTIBLE(可中断休眠,优先选择)或TASK_UNINTERRUPTIBLE(不可中断休眠,慎用)。
  3. 检查唤醒条件:再次检查目标事件是否已就绪(防止 “惊群效应” 或唤醒信号丢失),若已就绪,重置进程状态为TASK_RUNNING,无需休眠。
  4. 触发调度放弃 CPU:调用schedule(),触发调度并放弃 CPU,进程进入休眠状态,被从运行队列中移除。
  5. 休眠唤醒后清理:进程被唤醒后,首先重置进程状态为TASK_RUNNING,然后处理唤醒后的业务逻辑(如读取数据、释放资源)。
  6. 异常处理:若为可中断休眠,检查是否被信号中断,返回对应错误码。

set_current_state()函数

这是一个内核宏(封装了对当前进程task_struct的状态修改),核心作用是修改当前进程的state成员变量

函数原型(Linux 5.10)

#define set_current_state(state_value) \ do { \ current->state = (state_value); \ } while (0)
  • 常用参数(休眠状态)
    • TASK_INTERRUPTIBLE:可中断休眠,优先选择。进程会休眠等待事件,同时响应信号(如kill命令),被信号唤醒后会返回-ERESTARTSYS错误码,符合用户态进程使用习惯。
    • TASK_UNINTERRUPTIBLE:不可中断休眠。进程仅会被硬件事件 / 内核主动唤醒,忽略所有信号,无法被kill杀死,可能导致进程 “僵死”,仅用于驱动中必须等待硬件操作完成的场景(如磁盘 IO 完成)。
    • 禁止使用TASK_RUNNING:该宏用于设置休眠状态,设置为TASK_RUNNING无实际意义,应直接修改current->state或调用wake_up_process()

核心注意点:

  • 该宏仅修改状态,不做其他操作(如不将进程从运行队列移除,不放弃 CPU)。
  • 调用后必须尽快调用schedule(),否则进程仍持有 CPU,休眠状态无法生效。
  • 唤醒后必须手动重置进程状态为TASK_RUNNING,否则进程下次调度时会被误认为仍处于休眠状态,无法被正常挑选。

schedule()函数的配合行为

schedule()检测到当前进程状态为非TASK_RUNNING时,会执行额外逻辑:

  1. __schedule()中,调用dequeue_task()将当前进程从运行队列中移除。
  2. 标记进程的on_rq0,表示进程不在运行队列中。
  3. 挑选下一个进程并完成上下文切换,当前进程进入休眠,暂停执行。
  4. 当进程被唤醒并重新调度执行时,从schedule()返回,继续执行后续代码。

wait_event()系列宏的关联

wait_event()系列宏(驱动首选),内部就是封装了set_current_state()schedule(),二者是 “底层实现” 与 “上层封装” 的关系。

wait_event_interruptible(wq, condition)为例,其核心内部逻辑简化如下:

#define wait_event_interruptible(wq, condition) \ ({ \ int __ret = 0; \ if (!(condition)) { \ // 1. 设置可中断休眠状态(对应 set_current_state()) set_current_state(TASK_INTERRUPTIBLE); \ // 2. 循环检查条件,避免惊群效应 while (!(condition)) { \ // 3. 调用 schedule() 放弃 CPU schedule(); \ // 4. 检查信号中断 if (signal_pending(current)) { \ __ret = -ERESTARTSYS; \ break; \ } \ // 5. 重新设置休眠状态(防止调度过程中状态被修改) set_current_state(TASK_INTERRUPTIBLE); \ } \ // 6. 重置进程状态为运行态 set_current_state(TASK_RUNNING); \ } \ __ret; \ })

可以看到,wait_event()系列宏只是在set_current_state()schedule()的基础上,增加了循环检查条件、自动状态重置、封装信号处理等逻辑,让使用更安全、简洁,因此驱动中优先使用wait_event()而非直接调用二者。

常见问题与避坑指南

  1. 忘记重置进程状态:休眠唤醒后未调用set_current_state(TASK_RUNNING),导致进程下次被调度时,仍被认为是休眠状态,无法被正常挑选,出现 “进程消失” 或 “僵死”。
  2. 使用不可中断休眠:滥用TASK_UNINTERRUPTIBLE,导致进程无法被信号杀死,出现 “ps查看进程存在,但无法kill” 的情况,仅在必须等待硬件操作完成时使用。
  3. 在中断上下文调用set_current_state()schedule()仅能在进程上下文调用,中断上下文中调用会导致栈混乱、系统崩溃。
  4. 持有自旋锁时休眠:持有spin_lock()时调用二者,会导致死锁(自旋锁要求进程不能休眠、不能切换),休眠前必须释放所有自旋锁。
  5. 未处理惊群效应:未二次检查条件直接休眠,导致多个进程被同时唤醒,但只有一个进程能处理数据,其他进程白唤醒,增加系统开销。

总结

  1. set_current_state()+schedule()是 Linux 内核进程主动休眠的核心底层组合,前者设置休眠状态,后者放弃 CPU 触发调度。
  2. 标准使用流程为 “设置休眠状态 → 检查条件 → 调用schedule()→ 唤醒后重置运行状态 → 处理异常”,必须严格遵循以避免问题。
  3. 二者的上层封装是wait_event()系列宏,驱动中优先使用封装宏,更安全、简洁,底层内核开发可直接使用二者。
  4. 核心禁忌:中断上下文、持有自旋锁时不可使用,可中断休眠必须处理信号中断,唤醒后必须重置进程状态为TASK_RUNNING
http://www.jsqmd.com/news/336533/

相关文章:

  • 2026年江山欧派深度解析:从研发创新看木门专家的进阶之路 - 品牌推荐
  • 2026办公室翻新公司推荐:如何挑选专业可靠服务团队 - 品牌排行榜
  • 2026年热处理行业:三大核心趋势重塑未来 - 速递信息
  • 2026年成都短视频代运营公司10强榜单正式发布!动力无限登顶TOP1,实力领跑行业 - 朴素的承诺
  • FDA重新确立NMN膳食补充剂地位 W+端粒塔锚定赛道引领抗衰新纪元 - 速递信息
  • 出墙记录
  • 2026高端酒店设计公司推荐:聚焦品质与创新的行业精选 - 品牌排行榜
  • 元气AI助手功能一览:《国产智能Bot新标杆:你的全能数字工作伙伴》 - PC修复电脑医生
  • 表格识别目前sota
  • 解析:AI+大模型如何重塑金融科技质量底座,助力香港软件质量跃迁 - 博客万
  • 2026年江山欧派深度解析:从研发创新看木门巨擘的进阶之路 - 品牌推荐
  • 2026年广东佛山可靠的硅胶圈生产企业推荐,哪家性价比高 - 工业品牌热点
  • 40岁中年职场妈妈评测NMN口碑,NMN哪个牌子好?2026年NMN十大品牌评测 - 速递信息
  • 干货:防晒指标(SPF、UVA-PF、CW等等)不仅是数值,更要看怎么测、标准怎么选,合规怎么说?
  • 探讨断桥铝门窗生产厂家怎么选,欧莱诺门窗是优选之一 - mypinpai
  • 超越阈值与统计:一种融合时序分解与深度表示的突变点检测框架
  • 菊水PBZ20-20 PBZ40-10双极性电源
  • 2026 CRM 系统排行榜:5 大 CRM + 供应链一体化品牌深度对比选型指南 - 毛毛鱼的夏天
  • 电梯超载与保护系统设计(有完整资料)
  • 好未来单季营收7.7亿美元:同比增27% 净利1.3亿美元
  • 是德科技N9951A N9961A N9912A N9917A手持频谱分析仪
  • 聊聊2026年京津冀口碑不错的全屋定制工厂,哪家性价比高 - myqiye
  • 是德科技53220A 53230A 53210A频率计数器
  • 超声波避障小车(有完整资料)
  • 讯灵geo推广公司怎么选,结合讯灵AI渠道经理优势来判断 - 工业设备
  • pdf转图片
  • 2026年首篇3D打印Science!
  • 出租车计价器(有完整资料)
  • 探寻2026碳纤维增强硅酸钙板优质企业,这些品牌上榜,硬硅酸钙石保温板,碳纤维增强硅酸钙板品牌口碑推荐 - 品牌推荐师
  • 安捷伦34970A 34972A 34980A DAQ970A数据采集仪