较早的Linux内核无法抢占的原因是什么?


15

为什么最初的Linux开发人员选择实现非抢占式内核?是否保存同步?

据我所知,Linux是在90年代初期开发的,当时PC具有单个处理器。非抢占式内核在此类PC中有什么优势?但是,为什么多核处理器会降低优势?

Answers:


26

在Linux内核的上下文中,当人们谈论抢占时,他们通常指的是内核中断自身的能力-本质上是在运行内核代码时切换任务。允许发生这种情况非常复杂,这可能是导致内核抢占时间较长的主要原因。

起初,大多数内核代码无论如何都无法中断,因为它受到了大内核锁的保护。越来越多的内核代码逐渐消除了该锁定,从而允许并行并行调用多个内核(随着SMP系统变得越来越普遍,这一点变得越来越重要)。但这仍然不能使内核本身具有先发制人的优势。把更多的发展是,在最终PREEMPT_RT补丁集,其最终在主线内核合并(并且是能够先发制人的BKL反正)。如今,可以将内核配置为或多或少的可抢占式,这取决于所追求的吞吐量和延迟特性。有关详细信息,请参见相关的内核配置

从内核配置的解释中可以看到,抢占会影响吞吐量和延迟,而不是并发。在单CPU系统上,抢占还是有用的,因为它允许以较短的响应时间处理事件。但是,这也会导致吞吐量降低(因为内核花费时间来切换任务)。抢占允许单个或多个CPU系统中的任何给定CPU更快地切换到另一个任务。多CPU系统上的限制因素不是抢占,而是大的或其他的锁定:任何时候代码被锁定,都意味着另一个CPU无法开始执行相同的操作。


12

抢占式内核仅意味着没有大内核锁

从一开始,Linux就具有抢占式多任务处理(即用户代码是抢占式的)(据我所知,Linus上载到funet ftp服务器上的第一个Linux 0.0.1早已是抢先式多任务处理)。例如,如果执行了多个压缩或编译过程,则它们从第一刻起便并行执行。

与当时-广泛使用的Win31相反。在Win31上,如果任务是从“内核”获得CPU的,则默认情况下,它有责任确定何时将控制权交还给OS(或其他任务)。如果某个进程对此功能没有特殊支持(需要额外的编程工作),则在执行该功能时,所有其他任务都将被挂起。甚至集成到Win31中的大多数基本应用程序都可以正常工作。

抢占式多任务处理意味着任务无法根据需要分配CPU。相反,如果它们的时隙到期,则内核会将CPU移开。因此,在抢占式操作系统中,编写错误或运行不正常的进程不能冻结OS,也不能避免其他进程运行。Linux总是抢占用户空间进程。

Big Kernel Lock表示在某些情况下,在内核空间内,仍然可能会有一些锁,从而阻止其他进程运行受保护的代码。例如,您不能同时挂载多个文件系统-如果您提供了多个挂载命令,它们仍将连续执行,因为挂载需要分配大内核锁。

要使内核具有抢占性,就必须消除此大内核锁定,即使挂载和任何其他任务能够同时运行。这是一项艰巨的工作。

从历史上看,这通过增加对SMP(多CPU支持)的支持变得非常紧迫。第一次有真正的多CPU主板。后来将多个CPU(“核心”)集成到一个芯片中,今天真正的多CPU主板已经很少了(它们通常在昂贵的服务器系统中)。真正真正的单核系统(只有一个cpu,只有一个核)也很少见。

因此,您的问题的答案不是“什么是非抢占性的原因”,因为它始终是抢占性的。真正的问题是,是什么使抢先式内核执行真正必要。答案是这样的:多CPU多核系统的比例在增加。


我实际上并没有理解:(直到内核版本2.4之前,只有用户进程是抢占式的,而内核是非抢占式的。正如我之前回答的那样,我认为原因是将工作保存在抢占式同步死锁上实施单核过程。您怎么看?
Narden

@Narden我不知道你读过它。大约在1.3或2.0之前,即使正在运行多个进程,内核空间中也只能有一个进程。这个限制在2.0中被大致消除。直到2.4左右,才有了Big Kernel Lock(即同时安装多个文件系统不起作用)。
彼得-恢复莫妮卡

@Narden但这不是协作式多任务处理,不需要有任何过程有意地将CPU带回任务调度程序。是的,BKL可能正确执行此操作的原因可能是一项繁重的工作:1)必须拆分锁2)可能的情况下应使用无锁数据结构3)拆分的锁会导致死锁/活锁,它们通常是特别脏的,难以修复的错误,应该找到并修复所有这些错误4)所有驱动程序都应移植到内核API的更改中。
彼得-恢复莫妮卡

我在寻找答案的同时阅读了它,并且还将作为我正在学习的一门课程中的信息,即操作系统。
纳登

1
大内核锁可以防止其他线程在内核中执行时进入内核。只允许一个线程,因为内核从一开始就没有设计对称多处理。但是,抢占式内核的含义有所不同。传统上,仅当内核返回用户空间时才更改执行上下文。在抢占式内核中,可以在运行的内核代码中间抢占线程。
约翰·迈伦(JohanMyréen)

3

这不是技术问题的答案,而是针对 OP提出的特定问题的历史答案:“较早的Linux内核无法抢占的原因是什么?”

(我假设,正如@peterh在他的回答和评论中所解释的,OP通过“非抢占性”指的是以下事实中的一个或两个,即一个用户进程可能位于内核中(在API中)。时间和/或大内核锁定。)

莱纳斯·托瓦尔兹(Linus Torvalds)对学习操作系统的工作方式很感兴趣,而他学习的方法就是编写一个。他的模型,基础和初始开发环境是Minix,这是一种用于教育目的的现有OS(即非生产OS),它不是免费的(如当时的开源)-它不像啤酒那样免费,要么)。

因此,他写了一个没有抢先的内核(在其他答案中提到了Big Kernel Lock),因为如果您出于教育目的想要快速启动并运行新操作系统,那就是这样做的方法:这要简单得多。支持用户程序和设备的并发多重编程的内核已经足够困难-使内核本身并发是非常困难的。

如果他知道那么流行/有用/重要的Linux将会如何发展……他可能会以同样的方式做到这一点。(仅IMO,我不知道他的实际想法。)因为您必须走路才能跑步。

而且这种方式已经存在了很长一段时间,因为a)要使Linux变成今天(甚至是当时的样子)还有很多其他工作要做,并且b)进行更改将是一项艰巨的任务。 (如其他答案中所述)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.