5

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

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

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

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

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

如果它切换到用户模式,但在scheduler_tick()设定的时刻NEED_RESCHED和实际切换到用户模式的时刻p之间需要“很长”的时间——那么它使用的时间超过了它的量?

4

2 回答 2

2

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

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

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

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

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

于 2016-10-23T19:34:26.040 回答
-1

切换进程有两种方式:

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

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

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

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

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

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

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

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

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

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

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

于 2016-10-23T16:15:50.077 回答