内核 - 调度程序:在进程之间切换时会发生什么

Kernel - Scheduler : what happens when switching between process

上下文:

我真的不明白内核如何在超过其时间片时保存 运行 代码的状态。

我无法想象实际发生的事情。

问题:

1) 当前 运行 代码(及其堆栈?)存储在哪里?

2) 当内核再次 "see" 代码时,它是否会跟随一个偏移量继续运行,就好像什么都没发生一样?

我不清楚。

谢谢

这取决于 OS 但作为一般规则,有一个存储块保存有关每个进程的信息(通常称为进程控制块或 PCB)。此信息包括指向正在执行的当前代码行的指针和寄存器的内容等,因此进程可以从上次停止的地方重新开始。

此信息块属于 OS 本身而非进程,因此它在进程暂停后仍然存在。

程序代码本身并不存储在 PCB 中 - 它只是存在于内存或磁盘中。它甚至可以在进程之间共享,例如,多个进程可能 运行 运行同一个程序,每个进程在任何给定时间在代码中的不同点,每个进程都有自己的一组 'variables' 或数据该进程的程序的 运行 是唯一的。 OS 需要的只是变量和行号或指针,以了解特定进程在挂起时在代码中的位置,并且可以从该点重新开始。

值得注意的是,进程使用的任何 RAM 在重新启动时可能仍然存在,也可能不存在。一般来说,OS 会尽量在内存中保留最近使用或经常使用的 RAM 块(或 'pages')。但是,如果它需要释放 space,它可能会将 'page' 换出到磁盘,但磁盘访问要慢得多,因此希望避免换出可能会被使用的内存可能的话再来一次。

在最坏的情况下,OS 可能会发现它换出了一个进程,然后很快新进程需要使用一些必须从磁盘检索的内存。发生这种情况时它会暂停,因为检索需要很长时间 CPU 术语。然后可能会发生下一个进程也很快发现自己处于相同的情况。 OS 现在花费大量时间来交换进程和内存,而用于实际工作的时间却少得多 - 这通常称为 'thrashing'。

当前代码指令指针和当前堆栈指针存储在task_struct->iptask_struct->sp(对于x86)和新进程的task_struct->iptask_struct->sp并加载回spip 在 Linux 内核中调用 switch_to() 时注册。

内核的 switch_to() 在切换到新进程时会做很多事情,比如重置 EIP、堆栈、FPU、段描述符、调试寄存器。 然后内核的 switch_mm() 将虚拟内存映射从上一个进程切换到新进程。