【问题标题】:What is the difference between nonpreemptive and preemptive kernels, when switching to user mode?切换到用户模式时,非抢占式内核和抢占式内核有什么区别?
【发布时间】:2017-03-05 09:49:48
【问题描述】:

我正在阅读“了解 Linux 内核,第 3 版”,在第 5 章“内核抢占”一节中,它说:

所有进程切换都由switch_to 宏执行。在双方抢先 和非抢占式内核,进程切换发生在进程完成时 一些内核活动线程和调度程序被调用。但是,在非抢占式内核中,当前进程不能被替换,除非它即将切换 到用户模式

我仍然看不出非抢占式内核和抢占式内核之间的区别,因为您需要等待当前进程切换到用户模式。

假设有一个进程p在内核模式下运行,并且其时间片到期,则调用scheduler_tick(),并设置p的NEED_RESCHED标志时间>。 但是schedule() 仅在 p 切换到用户模式时调用(对吗?)。

如果 p 永远不会切换到用户模式怎么办?

如果它切换到用户模式,但在 scheduler_tick() 设置 NEED_RESCHEDp 实际切换到用户模式之间需要“很长时间” - 那么它使用的时间超过它的量子?

【问题讨论】:

  • 当你说“从不切换到用户模式”时,你是怎么想的?一个进程不太可能在内核模式下运行很长时间,要么被阻塞,要么处于等待状态,要么运行时间很短(或者内核设计不当)。
  • "但 schedule() 仅在 p 切换到用户模式时调用(对吗?)。 , 没有错。这就是重点,在内核中执行的进程不仅可以在返回用户空间时被抢占。
  • @nos 但它只是设置了一个标志,不调用 schedule()
  • @ManoMini 有很多地方检查了该标志。
  • @nos "当前进程无法被替换,除非它即将切换到用户模式"

标签: linux linux-kernel operating-system kernel preemption


【解决方案1】:

在非抢占式内核中,schedule() 在返回用户空间时被调用(以及系统调用阻塞的任何地方,也在空闲任务上)。

在抢占式内核中,schedule() 在从任何中断返回时也会被调用,在其他一些地方也会调用,例如在mutex_unlock() 慢速路径上,在某些条件下同时接收网络数据包,...

例如,假设进程 A 发出系统调用,该系统调用被设备生成的中断中断,然后被定时器中断中断:

 process A userspace → process A kernelspace → device ISR → timer ISR
                  syscall               device IRQ    timer IRQ

当定时器 ISR 结束时,它返回到另一个 ISR,然后返回到内核空间,然后返回到用户空间。抢占式内核检查是否需要在每次返回时重新调度进程。非抢占式内核仅在返回用户空间时进行检查。

【讨论】:

    【解决方案2】:

    切换进程有两种方式:

    1. 进程让出 CPU;或
    2. 操作系统对进程说“你现在已经完成了。”

    第一次发生在进程执行某些不允许它继续的操作时。例如,执行 SLEEP 类型的函数或执行 I/O(例如到磁盘或到终端并且必须等待用户响应)。

    第二个发生在操作系统的内部定时器关闭时,作为处理定时器中断的一部分,O/S 确定应该运行另一个进程。

    只处理第一种上下文切换的内核是非抢占式的。处理这两种上下文切换的内核是抢占式的。

    请注意,yield 需要执行系统服务。这需要触发异常来调用内核模式系统服务处理程序。

    抢占需要中断。在大多数非英特尔系统上,异常和中断的处理方式相同(英特尔提供了多种处理异常的方法)。在大多数系统上,中断和异常返回的过程是相同的。

    这两种情况下的上下文切换都发生在进程返回用户模式之前。当一个进程恢复执行时,首先要做的就是从内核模式返回到用户模式。

    但是,在非抢占式内核中,当前进程不能被替换,除非它即将切换到用户模式。

    这是一个定性的陈述。正常的产量顺序是:

    1. 触发异常
    2. 进入内核模式
    3. 分派到系统服务处理程序
    4. 做事
    5. 告诉操作系统让步。 上下文切换
    6. 发生了一些事件来告诉 O/S 进程可以再次运行。
    7. OS 在内核模式下恢复进程。
    8. 进程退出内核模式
    9. 进程在用户模式下以愉快的方式恢复。

    这本书的陈述是在#7 和#8 之间没有或很少发生。这通常是正确的,但系统服务完全有可能在那里做更多的工作。它只是不会正常发生。

    【讨论】:

    • linux 一直以您描述的两种方式处理切换过程。但是在遥远的过去(在 v 2.5.4 之前),在内核代码中执行的 linux 中的进程不能被抢占(被调度程序替换),除非是一个,并且只有内核中的特定代码路径 - 人们称之为这是一个非抢占式内核,以将其与使内核能够在执行内核代码时在许多其他点抢占进程的补丁(以及当前 linux 的工作方式)区分开来。
    • 这是 CPU 的显式让步。
    猜你喜欢
    • 2018-09-16
    • 2015-03-05
    • 1970-01-01
    • 2014-08-25
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    相关资源
    最近更新 更多