如果我正确理解上下文切换,该过程涉及两个主要步骤:
- MMU 被切换到将新进程的虚拟内存空间映射到物理内存空间。
- 为当前进程保存处理器状态,然后为新进程切换到保存的处理器状态。据推测,这包括将程序计数器设置为从切换到的进程上次停止的位置开始执行。
在内核中,处理所有这些的函数被称为context_switch()
(源代码在这里)。此函数处理两个必需的步骤,但在设置处理器状态后,它会返回。
这很令人困惑,因为在我看来,一旦程序计数器被手动移动到新位置,context_switch()
就根本没有机会返回。我能想到的唯一解释是,这context_switch()
都是切换到新进程的代码和切换进程返回的代码。换句话说,每个进程最终都会从自己的进程切换context_switch()
到另一个进程context_switch()
。但我似乎不清楚这如何在新分叉的进程中发挥作用。那么也许context_switch()
实际上运行完成并返回,然后其他东西跳转到目标进程的正确部分?
这种想法正确吗?到底在什么时候context_switch()
从一个流程转移到另一个流程?什么时候context_switch()
回来?当它切换到一个新进程时,它最终处于新进程的执行状态中的什么位置?这如何适应新分叉的进程?
在过去的几天里,我一直在阅读内核源代码的相关部分,试图弄清楚这一点,但恐怕我并没有更接近理解。希望这里有人可以提供帮助。
答案1
注意行中的注释3366(自 5.7.7 起):
/* Here we just switch the register state and the stack. */
context_switch()
不直接加载新的指令指针(程序计数器),它会切换堆栈 - 并且堆栈包含适当的返回地址。当函数返回时,它返回到新任务。
分叉时,虚拟返回地址与两个进程(父进程和子进程)中的虚拟返回地址相同;区别在于返回值。