V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
Richard14
V2EX  ›  问与答

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

  •  
  •   Richard14 · May 15, 2022 · 2140 views
    This topic created in 1446 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

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

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

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

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

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

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

    @CEBBCAT 单片机上课没认真学。不过我学过 8051 也不理解怎么睡眠的,你学过可以给我解释一下?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2475 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 50ms · UTC 09:30 · PVG 17:30 · LAX 02:30 · JFK 05:30
    ♥ Do have faith in what you're doing.