繁体   English   中英

说“Linux内核是抢占式的”是什么意思?

[英]What does it mean to say "linux kernel is preemptive"?

我读到 Linux 内核是抢占式的,这与大多数 Unix 内核不同。 那么,内核抢占式究竟意味着什么呢?

一些类比或例子会比纯理论解释更好。

添加 1 -- 11:00 AM 12/7/2018

抢占式只是多任务处理的一种范式。 还有其他的,比如协作多任务处理 通过比较它们可以更好地理解。

在 Linux 内核版本 2.5.4 之前,Linux 内核不是抢占式的,这意味着在内核模式下运行的进程无法移出处理器,直到它自己离开处理器或开始等待某些输入输出操作完成。

通常,处于用户模式的进程可以使用系统调用进入内核模式。 以前,当内核是非抢占式时,较低优先级的进程可以通过重复调用系统调用并保持内核模式来拒绝较高优先级进程访问处理器的优先级。 即使较低优先级进程的时间片过期,它也会继续运行,直到它完成在内核中的工作或自愿放弃控制权。 如果等待运行的优先级较高的进程是用户正在输入的文本编辑器或准备重新填充其音频缓冲区的 MP3 播放器,则结果是交互性能不佳。 这种方式非抢占式内核在当时是一个主要缺点。

想象一下抢占式多任务处理的简单视图。 我们有两个用户任务,它们都一直在运行,而不使用任何 I/O 或执行内核调用。 这两个任务无需执行任何特殊操作即可在多任务操作系统上运行。 内核,通常基于定时器中断,简单地决定是时候暂停一个任务让另一个任务运行。 有问题的任务完全不知道发生了什么。

然而,大多数任务偶尔会通过系统调用向内核发出请求。 发生这种情况时,存在相同的用户上下文,但 CPU 正在代表该任务运行内核代码。

较旧的 Linux 内核永远不会允许在忙于运行内核代码时抢占任务。 (请注意,I/O 操作总是自动重新调度。我说的是内核代码有一些 CPU 密集型操作,例如对列表进行排序的情况。)

如果系统允许该任务在运行内核代码时被抢占那么我们就有了所谓的“抢占内核”。 这样的系统不受系统调用期间可能遇到的不可预测的延迟的影响,因此它可能更适合嵌入式或实时任务。

例如,如果在特定 CPU 上有两个任务可用,一个需要 5 毫秒才能完成的系统调用,另一个是需要每 2 毫秒馈送音频管道的 MP3 播放器应用程序,您可能会听到断断续续的音频。

反对抢占的论点是所有可能在任务上下文中调用的内核代码都必须能够在抢占后幸存下来——例如,有很多糟糕的设备驱动程序代码,如果它总是能够在之前完成一个操作,那可能会更好允许其他任务在该处理器上运行。 (如今,对于多处理器系统而言,规则而不是例外,所有内核代码都必须是可重入的,因此该论点在今天不再相关。)此外,如果可以通过改进系统调用来实现相同的目标延迟,也许抢占是不必要的。

一个折衷方案是 CONFIG_PREEMPT_VOLUNTARY,它允许在内核内部的某些点进行任务切换,但不能在任何地方进行。 如果只有少数地方内核代码可能会陷入困境,这是一种减少延迟同时保持复杂性可管理的廉价方法。

传统的 Unix 内核只有一个锁,在内核代码运行时由一个线程持有。 因此没有其他内核代码可以中断该线程。

这使得设计内核更容易,因为您知道当一个线程使用内核资源时,没有其他线程使用。 因此不同的线程不能搞乱彼此的工作。

在单处理器系统中,这不会引起太多问题。

但是,在多处理器系统中,您可能会遇到不同处理器或内核上的多个线程都希望同时运行内核代码的情况。 这意味着根据工作负载的类型,您可能有很多处理器,但它们大部分时间都在等待对方。

在 Linux 2.6 中,内核资源被划分为更小的单元,由单独的锁保护,并检查内核代码以确保只有在使用相应资源时才持有锁。 因此,现在不同的处理器如果想要访问相同的资源(例如硬件资源),只需相互等待即可。

抢占允许内核提供并行性的印象:您只有一个处理器(假设是十年前),但您感觉所有进程都在同时运行。 那是因为内核抢占(即,取消执行)一个进程的执行以将其交给下一个进程(可能根据它们的优先级)。

编辑不是抢占式内核等待进程交还手(即,在系统调用期间),因此如果您的进程计算大量数据并且不调用任何类型的yield函数,则其他进程将无法执行执行他们的电话。 这样的系统被称为合作的,因为它们要求进程的合作以确保执行时间的公平

编辑 2抢占的主要目标是提高系统在多个任务之间的反应性,这对最终用户有好处,而另一方面,服务器想要实现最高吞吐量,所以他们不需要它: (来自Linux内核配置)

linux 内核是单片的,并为所有正在运行的进程顺序提供了一点计算时间跨度。 这意味着进程(例如程序)不会同时运行,但会定期给它们一个给定的时间跨度来执行它们的逻辑。 主要问题是某些逻辑可能需要更长时间才能终止并阻止内核为下一个进程留出时间。 这会导致系统“滞后”。

抢先内核具有切换上下文的能力。 这意味着即使它没有完成,它也可以停止“挂起”的进程,并按预期将计算时间交给下一个进程。 “挂起”进程将在没有任何问题的时间到来时继续执行。

实际上,这意味着内核具有实时完成任务的能力,这对于音频录制和编辑来说尤其有趣。

ubuntu 工作室发行版打包了一个抢占式内核以及大量专用于音频和视频版本的优质免费软件。

这意味着操作系统调度程序可以自由地暂停正在运行的进程的执行,以便在需要时将 CPU 交给另一个进程; 执行此操作的正常方法是为每个等待 CPU 的进程提供一个“量子”的 CPU 运行时间。 在它到期后,调度程序收回控制权(并且正在运行的进程无法避免这种情况)以将另一个量程分配给另一个进程。

这种方法通常与协作多任务处理相比,在协作多任务处理中,进程在它们需要的所有时间都保持 CPU,不被中断,并且为了让其他应用程序运行,它们必须显式调用某种“yield”函数; 自然地,为了避免给人一种系统卡住的感觉,表现良好的应用程序会经常让出 CPU。 尽管如此,如果应用程序中存在错误(例如,没有yield 调用的无限循环)整个系统将挂起,因为CPU 完全由错误程序保留。

几乎所有最近的桌面操作系统都使用抢占式多任务处理,即使它在资源方面更昂贵,通常也更稳定(单个故障应用程序更难以挂起整个系统,因为操作系统始终处于控制之中)。 另一方面,当资源紧张并且期望应用程序表现良好时,使用协作多任务处理。 Windows 3 是一个协作式多任务操作系统; 最近的一个例子是 RockBox,一个开源 PMP 固件替代品。

我认为每个人都很好地解释了这一点,但我只想添加更多信息。 在 Linux IRQ、中断和内核调度程序的上下文中。

进程调度程序是操作系统的一个组件,负责决定当前正在运行的作业/进程是否应该继续运行,如果不是,接下来应该运行哪个进程。

抢占式调度程序是一个允许被中断的调度程序,一个正在运行的进程可以改变它的状态,然后让另一个进程运行(因为当前进程被中断了)。

另一方面,非抢占式调度程序不能从进程(又名合作)中夺走 CPU仅供参考,名称词“合作”可能会令人困惑,因为该词的含义并没有清楚地表明调度程序实际做什么。

例如,像 3.1 这样的旧 Windows 具有协作调度程序。

完全归功于这里的精彩文章

Linux 内核是抢占式意味着内核支持抢占式。

例如,有两个进程 P1(较高优先级)和 P2(较低优先级)正在执行读取系统调用并且它们在内核模式下运行。 假设 P2 正在运行并且处于内核模式,并且 P2 计划运行。

如果内核抢占可用,那么抢占可以发生在内核级别,即 P2 可以被抢占,但进入睡眠状态,P1 可以继续运行。

如果内核抢占不可用,由于 P2 处于内核模式,系统只需等待 P2 完成,然后

我认为它是从 2.6 开始的。 抢占意味着当一个新进程准备运行时,cpu将分配给新进程,它不需要正在运行的进程合作并放弃cpu。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM