我读到Linux内核是先发制人的,这与大多数Unix内核不同。那么,核心先发制人意味着什么呢?
一些类比或例子比纯粹的理论解释更好。
Preemptive只是多任务的一种范例。还有其他像Cooperative Multi-tasking。通过比较可以更好地理解。
答案 0 :(得分:24)
在Linux内核版本2.5.4之前,Linux内核不抢占,这意味着在内核模式下运行的进程无法移出处理器,直到它自己离开处理器或开始等待某些输入输出操作才能完成。
通常,用户模式下的进程可以使用系统调用进入内核模式。以前,当内核是非抢占式时,优先级较低的进程可以通过重复调用系统调用并保留在内核模式中来拒绝对处理器的访问来优先反转更高优先级的进程。即使优先级较低的进程'时间片到期,它也将继续运行,直到它完成其在内核中的工作或自愿放弃的控制。如果等待运行的较高优先级进程是用户正在键入的文本编辑器或准备重新填充其音频缓冲区的MP3播放器,则结果是交互性能差。这种方式非抢占式内核是当时的一个主要缺点。
答案 1 :(得分:18)
想象一下先发制人多任务的简单观点。我们有两个用户任务,它们都在不使用任何I / O或执行内核调用的情况下一直运行。这两项任务不需要做任何特殊的事情就可以在多任务操作系统上运行。内核通常基于定时器中断,只是决定一个任务暂停以让另一个任务运行的时间。有问题的任务完全没有意识到发生了什么。
但是,大多数任务都会通过系统调用偶尔发出内核请求。发生这种情况时,存在相同的用户上下文,但CPU代表该任务运行内核代码。
旧的Linux内核在繁忙运行内核代码时永远不会允许抢占任务。 (请注意,I / O操作总是自动重新安排。我在谈论内核代码有一些CPU密集型操作的情况,比如对列表进行排序。)
如果系统允许该任务在运行内核代码时被抢占,那么我们就拥有所谓的“抢先内核”。这样的系统不受系统调用期间可能遇到的不可预测的延迟的影响,因此它可能更适合嵌入式或实时任务。
例如,如果在特定的CPU上有两个可用的任务,一个需要一个需要5ms才能完成的系统调用,另一个是需要每隔2ms输入音频管道的MP3播放器应用程序,你可能会听到口吃音频。
反对抢占的论点是,可能在任务上下文中调用的所有内核代码都必须能够在抢占中生存 - 例如,如果它始终能够完成,那么可能会有更好的设备驱动程序代码。允许其他任务在该处理器上运行之前的操作。 (现在多处理器系统是规则而不是例外,所有内核代码必须是可重入的,因此这个参数今天不那么重要。)另外,如果通过改善系统调用可以实现相同的目标延迟,也许是先发制人是不必要的。
妥协是CONFIG_PREEMPT_VOLUNTARY,它允许在内核中的某些点进行任务切换,但不是在任何地方。如果只有少数几个内核代码可能陷入困境的地方,这是一种减少延迟同时保持复杂性可管理的廉价方法。
答案 2 :(得分:7)
传统的unix内核有一个锁,在内核代码运行时由一个线程持有。因此,没有其他内核代码可以中断该线程。
这使得设计内核变得更容易,因为你知道当一个线程使用内核资源时,没有其他线程。因此,不同的线程不能搞砸彼此的工作。
在单处理器系统中,这不会导致太多问题。
但是在多处理器系统中,您可能会遇到不同处理器或内核上的多个线程都希望同时运行内核代码的情况。这意味着根据工作负载的类型,您可以拥有大量处理器,但所有处理器都将大部分时间用于等待彼此。
在Linux 2.6中,内核资源被划分为更小的单元,受到单独锁的保护,并且审查了内核代码以确保仅在相应资源被使用时保持锁。所以现在不同的处理器只有在想要访问相同的资源(例如硬件资源)时才必须等待。
答案 3 :(得分:5)
抢占允许内核给出并行性的IMPRESSION:你只有一个处理器(让我们说十年前),但你觉得你的所有进程都是同时运行的。这是因为内核从一个进程抢占(即执行执行)执行以将其提供给下一个进程(可能根据它们的优先级)。
编辑不抢占式内核等待进程回放手(即在系统调用期间),因此如果您的进程计算大量数据并且未调用任何类型的yield
函数,其他进程将无法执行以执行其调用。据说这样的系统是合作,因为他们要求流程的合作以确保执行时间的公平性
EDIT 2 抢占的主要目标是提高系统在多个任务中的反应性,这对最终用户有利,而另一方面,服务器希望达到最高througput,所以他们不需要它:(来自Linux内核配置)
答案 4 :(得分:3)
这意味着操作系统调度程序可以自由地暂停正在运行的进程的执行,以便在需要时为CPU提供另一个进程;执行此操作的常规方法是为每个等待CPU的进程提供运行CPU时间的“量子”。在它到期后,调度程序收回控件(并且正在运行的进程无法避免这种情况),以便为另一个进程提供另一个量程。
这种方法通常与协作式多任务进行比较,在这种方法中,进程会一直保持CPU所需的时间而不会被中断,并且为了让其他应用程序运行,他们必须明确地调用某种“yield”函数;当然,为了避免让系统感觉卡住,性能良好的应用程序会经常产生CPU。但是,如果应用程序中存在错误(例如,没有yield调用的无限循环),整个系统将挂起,因为CPU完全由错误的程序保存。
几乎所有最近的桌面操作系统都使用抢先式多任务处理,即使它在资源方面更加昂贵,通常也更稳定(因为操作系统总是处于运行状态,因此一个错误的应用程序挂起整个系统会更加困难控制)。另一方面,当资源紧张且预期应用程序表现良好时,使用协作式多任务处理。 Windows 3是一个合作的多任务操作系统;最近的一个例子可以是RockBox,一个开源PMP固件替代品。
答案 5 :(得分:2)
Linux内核是单片式的,并且按顺序为所有正在运行的进程提供一点计算时间。这意味着进程(例如程序)不会同时运行,但是它们会定期给出一个给定的时间来执行它们的逻辑。主要问题是某些逻辑可能需要更长时间才能终止并阻止内核为下一个进程留出时间。这导致系统“滞后”。
preemtive内核具有switch context的能力。这意味着即使它没有完成它也可以停止“挂起”过程,并按预期将计算时间提供给下一个过程。 “悬挂”过程将在时间到来时继续执行,没有任何问题。
实际上,这意味着内核能够实时完成任务,这对于录音和编辑尤其有用。
ubuntu studio districution打包抢占式内核以及一系列专门用于音频和视频版本的高质量免费软件。
答案 6 :(得分:1)
我认为每个人都很好地解释了这一点,但我只想补充一点信息。在Linux IRQ,中断和内核调度程序的环境中。
进程调度程序是OS的组件,负责确定当前正在运行的作业/进程是否应继续运行,以及是否应继续运行。
抢占式调度程序是一种调度程序,它可以被中断,并且正在运行的进程可以更改其状态,然后让另一个进程运行(因为当前进程被中断)。
另一方面,非抢占式调度程序无法将CPU从进程(又称为协作)中夺走 仅供参考,“合作”一词的名称可能会引起混淆,因为该词的含义不能清楚地表明调度程序的实际作用。
例如,较旧的Windows(如3.1)具有协作调度程序。
功不可没article here
答案 7 :(得分:0)
我认为它从2.6开始成为先发制人。 preemptive意味着当一个新进程准备运行时,cpu将被分配给新进程,它不需要运行进程合作并放弃cpu。
答案 8 :(得分:0)
Linux内核抢先意味着内核支持抢占。
例如,有两个进程P1(较高优先级)和P2(较低优先级)正在执行读取系统调用,并且它们在内核模式下运行。假设P2正在运行并且处于内核模式并且P2计划运行。
如果内核抢占可用,那么抢占可能发生在内核级别,即P2可以被抢占,但是要睡眠,P1可以继续运行。
如果内核抢占不可用,由于P2处于内核模式,系统只需等待P2完成然后