我的操作系统教科书上是这么写的:
中断会导致操作系统将 CPU 核心从当前任务更改为运行内核例程。将CPU核心切换到另一个进程需要执行当前进程的状态保存和不同进程的状态恢复。此任务称为上下文切换。
由此看来,中断会导致上下文切换就很好理解了。中断是上下文切换的唯一方式吗?或者即使没有中断,我们也可以切换上下文吗?上下文切换只在线程和进程的上下文中有效吗?
答案1
当内核代码在特权处理器模式下运行时,操作系统可以执行上下文切换,而不管它是如何到达那里的。
正如您书中所写,当中断到达 CPU 核心时,可能会发生这种情况。然后内核更改为特权模式并运行内核安装的适当中断处理程序。然后,内核可能决定切换到另一个进程/线程的上下文,或者将控制权交还给被中断的任务。中断是唯一的方法不由自主交换正在运行的任务。
另一种可能导致上下文切换的方式是当任务执行系统调用时(例如sched_yield
、recv
等)sched_yield
直接要求内核将 CPU 让出给另一个任务,但是recv
如果系统仍然必须等待接收数据,则例如也可能导致上下文切换。
上下文切换只在线程和进程的上下文中有效吗?
由于上下文切换保存一个任务的状态并恢复另一个任务的状态,并且任务通常称为“线程”,而具有某些公共状态的线程组通常称为“进程”,因此可以公平地说,上下文切换在操作系统级别总是在线程和/或进程之间完成。然而,该术语有时会被重复使用,例如绿线在用户空间中。
答案2
cpu 上下文(regs、一些表)由于切换过程而发生变化。从用户模式到内核模式并不是一个完整的上下文切换,因为只更改了很少的寄存器:相同的进程仍在运行,但是运行一些由内核实现的代码,如 i/o 或页面更新等。现在,完整的由于中断(计时器、故障、硬件)或进程在请求 I/O 后被阻塞,上下文会发生更改。
答案3
上下文切换仅在……上下文(不仅要考虑 cpu 寄存器的值,还要考虑页表、打开文件处理程序、权限……)需要……切换(为其他人更改)时发生。
除了您已经了解的中断处理之外,这个概念仅在多处理的上下文中才知道,因为在单处理的情况下......总是有一个独特的上下文。
系统调用本身不会触发上下文切换,因为内核在执行过程时需要在调用进程上下文中运行,而且完成后,执行可能会在调用进程的下一条指令上恢复,就像普通的操作一样子程序已被调用。
然而,在某些情况下(例如,阻塞读取某些打开的描述符),内核知道不应在调用进程中恢复执行。 (因为它应该等待某些事件的发生)
相反,应该为调度程序提供机会将进程调度出去并调度另一个进程。上下文必然会发生变化(有利于调度的进程)进程上下文)=> 必须发生上下文切换。
总而言之,上下文切换将系统地在某些 IRQ 触发后立即发生(因为 IRQ 处理程序永远不会代表任何进程执行),而上下文切换可能发生在某些系统调用执行的某个时刻,具体取决于可能的调度机会。