V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Richard14
V2EX  ›  问与答

操作系统实现睡眠的原理是什么呢?

  •  
  •   Richard14 · 2022-05-15 17:44:49 +08:00 · 1549 次点击
    这是一个创建于 683 天前的主题,其中的信息可能已经有所发展或是发生改变。

    朋友分享的面试题,我也不会。

    正常来说程序只有两种状态,一种是正在运行,另一种是运行完了,从这个角度考虑的话那程序宇宙里就不存在睡眠这种东西,唯一实现类似睡眠功能的就是执行一个需要花那么长时间的计算,占满 CPU 所以就“睡眠”了。

    不过现代由于程序不是直接跑在硬件上,而是多加了一层操作系统,那么程序就可以要求操作系统挂起自己,到时间了再唤醒,由此实现了睡眠。但操作系统层面是如何搞定计时功能的呢?有没有熟悉底层原理的大佬分享一下,CPU 上是有个专门负责计时的硬件吗?印象里 CPU 听说过有固定频率的发生器,但是好像没听说过有基于这个发生器跑计时之类功能的硬件。。

    第 1 条附言  ·  2022-05-15 21:04:07 +08:00
    贴个条,楼下老哥们理解错了。发帖时候逻辑是进程 sleep->依赖操作系统->操作系统如何完成。结果发帖写做系统睡眠以后,似乎和系统的 hibernate 混淆了,不是指休眠那个意思
    14 条回复    2022-05-16 01:44:45 +08:00
    cpstar
        1
    cpstar  
       2022-05-15 17:55:05 +08:00
    大学有一门课程就叫《操作系统》,该门课程有一部分内容就在讨论进程状态(请自行搜索图片)——进程有一个状态是挂起,相当于休眠 /睡眠。这是软件层面的。

    然后这个问题,额,操作系统实现睡眠,看来其更像是包括硬件层面的。操作系统根据硬件能力,设置自身状态,执行硬件的指令,使机器睡眠——当然还要做好相应机制(其实就是睡眠前设定的参数),能够保证醒来一切正常。

    然后,这个问题吧,额,基础课程的作用就是这个了。
    sora2blue
        2
    sora2blue  
       2022-05-15 18:12:30 +08:00   ❤️ 1
    正好最近看到少数派[一篇文章]( https://sspai.com/post/72757)就是讲睡眠的
    irytu
        3
    irytu  
       2022-05-15 18:17:29 +08:00 via iPhone
    睡眠其实是不被调度,这个时候会保留上下文和内核堆栈,唤醒是由硬件中断触发的,这个时候进程被调度。操作系统有算法去调度进程,决定是否睡眠还是被调度,进程也可以主动告知操作系统睡眠并让出时间片,本质上还是处于不被调度的状态
    2NUT
        4
    2NUT  
       2022-05-15 18:20:57 +08:00
    我的妈呀, 除了 内存 其他都断电呀

    睡眠 休眠是 电源管理模块控制的, s0 s1~ s5, cpu 在这些级别下都不工作

    你说的 程序状态是 进程管理 完成的, 不是一个层级.
    AzadCypress
        5
    AzadCypress  
       2022-05-15 18:21:47 +08:00
    操作系统实现多任务调度依赖的是中断机制,时钟中断触发中断处理程序进行任务调度,然后在调度时的处理可以实现 sleep
    Jooooooooo
        6
    Jooooooooo  
       2022-05-15 18:36:32 +08:00
    有一种特殊的"睡眠任务", 在没有事可做的时候就会"运行"这个任务.

    然后定时的中断会打断这个任务从而能正常执行其它任务.
    Jooooooooo
        7
    Jooooooooo  
       2022-05-15 18:38:16 +08:00
    可以搜 idle task
    wy315700
        8
    wy315700  
       2022-05-15 18:41:34 +08:00
    OP 说的是进程的睡眠吧。。
    常见的消费操作系统都是分时系统,把 CPU 时间分成一片片的。每一片时间到了以后,CPU 会产生一个时钟中断,然后由调度器决定下一个时间片跑哪个线程。
    Richard14
        9
    Richard14  
    OP
       2022-05-15 21:06:19 +08:00
    @wy315700 感觉不太对,系统调度线程的分片粒度印象里挺粗的,在 10 毫秒的数量级,那岂不是意味着程序 sleep1 秒唤醒这种操作有 10ms 的误差,实际上睡眠唤醒精度挺高的,linux 测下来在微秒的数量级
    wy315700
        10
    wy315700  
       2022-05-15 21:18:33 +08:00
    @Richard14
    你可以试试看系统满载的情况下 sleep 的精度是多少
    sleep 的精度就是秒。当然如果系统负载低的时候可以测出来微妙级别的误差。

    微秒的数量级应该用 usleep (不精确)或者 select (精确)
    misaka19000
        11
    misaka19000  
       2022-05-15 21:31:20 +08:00
    楼主没学过操作系统? sleep 用的是时钟中断,时钟中断用的是时钟或者说是晶振实现的
    misaka19000
        12
    misaka19000  
       2022-05-15 21:34:23 +08:00
    一般的操作系统中,中断在进程处理队列中一般优先级极高,可以近似的看成是实时的
    CEBBCAT
        13
    CEBBCAT  
       2022-05-15 22:13:36 +08:00 via iPhone
    8051 学一下

    PS 我开玩笑的,现在都推荐学 ESP32 了
    Richard14
        14
    Richard14  
    OP
       2022-05-16 01:44:45 +08:00
    @wy315700 默认都用 select 实现确保精度,不过 select 如何实现在指定时间发出中断呢?

    @CEBBCAT 单片机上课没认真学。不过我学过 8051 也不理解怎么睡眠的,你学过可以给我解释一下?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5740 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 06:09 · PVG 14:09 · LAX 23:09 · JFK 02:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.