Multithreading 语境转换的步骤

Multithreading 语境转换的步骤,multithreading,process,context-switch,Multithreading,Process,Context Switch,我被要求描述上下文切换(1)在两个不同进程之间以及(2)在同一进程中的两个不同线程之间所涉及的步骤 在上下文切换期间,内核将在其PCB中保存旧进程的上下文,然后加载计划运行的新进程的保存上下文 操作系统可以安排同一进程中两个不同线程之间的上下文切换,使它们看起来并行执行,因此通常比两个不同进程之间的上下文切换快 这是否过于笼统,或者您会添加哪些内容来更清楚地解释流程?按照相反的顺序解释这些内容要容易得多,因为流程切换总是涉及线程切换 单核CPU上的典型线程上下文切换如下所示: 所有上下文开关都由

我被要求描述上下文切换(1)在两个不同进程之间以及(2)在同一进程中的两个不同线程之间所涉及的步骤

  • 在上下文切换期间,内核将在其PCB中保存旧进程的上下文,然后加载计划运行的新进程的保存上下文
  • 操作系统可以安排同一进程中两个不同线程之间的上下文切换,使它们看起来并行执行,因此通常比两个不同进程之间的上下文切换快

  • 这是否过于笼统,或者您会添加哪些内容来更清楚地解释流程?

    按照相反的顺序解释这些内容要容易得多,因为流程切换总是涉及线程切换

    单核CPU上的典型线程上下文切换如下所示:

  • 所有上下文开关都由“中断”启动。这可能是运行驱动程序的实际硬件中断(例如,从网卡、键盘、内存管理或定时器硬件),或执行硬件中断(如调用序列)以进入操作系统的软件调用(系统调用)。在驱动程序中断的情况下,操作系统提供了一个入口点,驱动程序可以调用该入口点,而不是执行“正常”直接中断返回&因此,如果驱动程序需要操作系统设置线程就绪(例如,它发出了信号量),则允许驱动程序通过操作系统调度程序退出

  • 非平凡系统必须启动硬件保护级别更改,以进入内核状态,以便可以访问内核代码/数据等

  • 必须保存中断线程的核心状态。在一个简单的嵌入式系统上,这可能只是将所有寄存器推送到线程堆栈上,并将堆栈指针保存在其线程控制块(TCB)中

  • 在这个阶段,许多系统切换到操作系统专用堆栈,这样操作系统内部堆栈的大部分需求就不会施加在每个线程的堆栈上

  • 为了允许嵌套中断,可能需要标记发生中断状态更改的线程堆栈位置

  • 驱动程序/系统调用运行,并可能通过从不同线程优先级的内部队列中添加/删除TCB来更改就绪线程集,例如,网卡驱动程序可能已设置事件或向另一个线程正在等待的信号量发出信号,以便将线程添加到就绪线程集,或者,一个正在运行的线程可能调用了sleep(),因此选择将自己从就绪集中移除

  • 运行OS调度程序算法以决定下一个要运行的线程,通常是处于该优先级队列前面的最高优先级就绪线程。如果下一个要运行的线程与前一个运行的线程属于不同的进程,那么这里需要一些额外的东西(见下文)

  • 从TCB为该线程保存的堆栈指针将被检索并加载到硬件堆栈指针中

  • 所选线程的核心状态已恢复。在我的简单系统中,寄存器将从所选线程的堆栈中弹出。更复杂的系统将必须处理返回到用户级别的保护

  • 执行中断返回,因此将执行转移到所选线程

  • 在多核CPU的情况下,事情更加复杂。调度程序可能会决定,当前正在另一个内核上运行的线程可能需要停止,并由刚刚就绪的线程替换。它可以通过使用其处理器间驱动程序硬件中断运行必须停止的线程的内核来实现这一点。这个操作的复杂性,加上所有其他东西,是避免编写操作系统内核的一个很好的理由:)

    典型的流程上下文切换如下所示:

  • 进程上下文切换是由线程上下文切换启动的,因此上述1-9项都需要执行

  • 在上面的步骤5中,调度程序决定运行一个线程,该线程属于与先前运行的线程所属进程不同的进程

  • 内存管理硬件必须加载新进程的地址空间,即允许新进程的线程访问其内存的任何选择器/段/标志/任何东西

  • 需要从PCB保存/恢复任何FPU硬件的上下文

  • 可能需要保存/恢复其他流程专用硬件


  • 在任何实际系统上,这些机制都是依赖于体系结构的,上述内容对上下文切换的含义都是一个粗略而不完整的指南。进程切换产生的其他开销不是严格意义上的交换机的一部分-进程切换后可能会有额外的缓存刷新和页面错误,因为它的一些内存可能已被分页,而有利于属于拥有之前运行的线程的进程的页面。

    我希望我可以提供更多的解决方案详细/清晰的图片

    首先,操作系统调度线程,而不是进程,因为线程是系统中唯一的可执行单元。进程切换只是一个线程切换,其中线程属于不同的进程,因此过程基本相同

  • 调度程序被调用。这可能发生在三种基本情况下:

    • 非自愿的转变。在当前运行的线程之外发生了一些影响调度的外部事件。例如,过期的计时器唤醒了具有高优先级的线程;或者磁盘控制器已报告文件的请求部分已读入内存,等待它的线程可以继续执行;或者系统计时器告诉内核线程的时间量用完了;等等
    • 自动切换。线程显式地请求