现在,有一件事我一直想知道:Slear()是如何实现的?

如果这一切都是关于使用操作系统的API,那么API是如何制作的?

这一切都归结为在CPU上使用特殊的机器代码吗?CPU是否需要一个特殊的协处理器或其他小发明,如果没有它,你就无法进行睡眠()?

sleep()最著名的体现是在C语言中(更准确地说,是在C编译器附带的库中,比如GNU的libc),尽管现在几乎每一种语言都有它的类似功能,但在某些语言中实现sleep(想想Bash)并不是我们在这个问题中要看的...

编辑:在阅读了一些答案后,我看到流程被放在等待队列中.从那里,我也可以猜到两种 Select

  1. 设置计时器,以便内核在适当的时间唤醒进程,或者
  2. 每当内核被允许使用时间片时,它都会轮询时钟以判断是否到了唤醒进程的时间.

答案只提到了备选方案1.因此,我问:这个计时器的行为如何?如果只是一个简单的中断让内核唤醒进程,内核怎么能要求计时器"在140毫秒内唤醒我,这样我就可以让进程处于运行状态"?

推荐答案

这个问题的"更新"显示了对现代OSs工作原理的一些误解.

内核不被"允许"使用时间片.内核是给用户进程分配时间片的东西."计时器"没有设置为唤醒Hibernate 进程-它设置为停止当前运行的进程.

本质上,内核试图通过停止CPU上运行时间过长的进程来公平分配CPU时间.简而言之,假设所有进程使用CPU的时间都不允许超过2毫秒.因此,内核会将计时器设置为2毫秒,并让进程运行.当计时器触发中断时,内核获得控制权.它保存正在运行的进程的当前状态(寄存器、指令指针等),并且控制权不会返回给它.取而代之的是,从等待分配CPU的进程列表中挑选另一个进程,并且被中断的进程被放到队列的后面.

睡眠进程在等待CPU的事物队列中只占not个.相反,它存储在睡眠队列中.每当内核收到计时器中断时,就会判断睡眠队列,并且时间已到的进程会被转移到"等待CPU"队列.

当然,这是一个粗略的简化.它需要非常复杂的算法来确保安全性、公平性、平衡性、优先级、防止饥饿、快速完成所有这些操作,并且使用最少的内存用于内核数据.

C++相关问答推荐

Visual Studio和Codebocks中的不同输出

strftime函数中%s的历史意义是什么?为什么没有记录?

带有sigLongjMP中断I/O的异常处理程序

C语言编译阶段与翻译阶段的关系

向上强制转换C中的数值类型总是可逆的吗?

试图从CSV文件中获取双精度值,但在C++中始终为空

在基本OpenGL纹理四边形中的一个三角形中进行渲染

在C++中访问双指针

CC2538裸机项目编译但不起作用

S的这种管道实施有什么问题吗?

预处理器宏扩展(ISO/IEC 9899:1999(E)§;6.10.3.5示例3)

类型定义 struct 与简单的类型定义 struct

在函数外部使用内联ASM时无法指定操作数

C标准关于外部常量的说明

合并对 struct 数组进行排序

赋值两侧的后置增量,字符指针

意外的C并集结果

指向返回 struct 成员的指针,安全吗?

GDB 跳过动态加载器代码

无法在线程内用 C 打印?