导航:首页 > 编程系统 > 禁止linux内核抢占

禁止linux内核抢占

发布时间:2024-08-16 03:12:22

㈠ 实时操作系统中说的抢占式和可剥夺内核是同一个意思吗

是一个意思。抄
实时系统可分袭两类:可抢占式(可剥夺。如VxWorks)和非抢占式(不可剥夺。如linux)系统。
通常,后者采用时间片轮询方式调度,前者则严格按照优先级调度。什么意思呢?假设有两个任务:高优先级任务T1和低优先级任务T2。
某一时刻,T2正在运行,没有执行完,而T1就绪(比如在硬中断里发生了事件需要响应)。此时,两种内核的调度行为差别是:
——非抢占式内核:只有等T2执行完释放CPU,T1才能运行;
——抢占式内核:退出就绪T1任务的中断时就会产生调度行为,结果是T2被悬挂,T1立即得到执行。即:T1抢占了(剥夺了)T1的CPU资源。

㈡ linux内核中造成并发执行的原因是什么

linux中内核并发机制也就是同步机制产生的原因,总的来说可归纳为一下4点:
l 中断——中断几乎可以在任何时刻异步发生,也就可能随时打断当前正在执行的代码
2 睡眠及与用户空间的同步——在内核执行的进程可能会睡眠,这就会唤醒调度程序,从而导致调度一个新的用户进程执行。
3 对称多处理——两个或多个处理器可以同时执行代码。
4内核抢占——因为内核具有抢占性,所以内核中的任务可能会被另一任务抢占(在2.6内核引进的新能力)。

㈢ linux环境下的进程调度算法有哪些

第一部分: 实时调度算法介绍

对于什么是实时系统,POSIX 1003.b作了这样的定义:指系统能够在限定的响应时间内提供所需水平的服务。而一个由Donald Gillies提出的更加为大家接受的定义是:一个实时系统是指计算的正确性不仅取决于程序的逻辑正确性,也取决于结果产生的时间,如果系统的时间约束条件得不到满足,将会发生系统出错。

实时系统根据其对于实时性要求的不同,可以分为软实时和硬实时两种类型。硬实时系统指系统要有确保的最坏情况下的服务时间,即对于事件的响应时间的截止期限是无论如何都必须得到满足。比如航天中的宇宙飞船的控制等就是现实中这样的系统。其他的所有有实时特性的系统都可以称之为软实时系统。如果明确地来说,软实时系统就是那些从统计的角度来说,一个任务(在下面的论述中,我们将对任务和进程不作区分)能够得到有确保的处理时间,到达系统的事件也能够在截止期限到来之前得到处理,但违反截止期限并不会带来致命的错误,像实时多媒体系统就是一种软实时系统。

一个计算机系统为了提供对于实时性的支持,它的操作系统必须对于CPU和其他资源进行有效的调度和管理。在多任务实时系统中,资源的调度和管理更加复杂。本文下面将先从分类的角度对各种实时任务调度算法进行讨论,然后研究普通的 Linux操作系统的进程调度以及各种实时Linux系统为了支持实时特性对普通Linux系统所做的改进。最后分析了将Linux操作系统应用于实时领域中时所出现的一些问题,并总结了各种实时Linux是如何解决这些问题的。

1. 实时CPU调度算法分类

各种实时操作系统的实时调度算法可以分为如下三种类别[Wang99][Gopalan01]:基于优先级的调度算法(Priority-driven scheling-PD)、基于CPU使用比例的共享式的调度算法(Share-driven scheling-SD)、以及基于时间的进程调度算法(Time-driven scheling-TD),下面对这三种调度算法逐一进行介绍。

1.1. 基于优先级的调度算法

基于优先级的调度算法给每个进程分配一个优先级,在每次进程调度时,调度器总是调度那个具有最高优先级的任务来执行。根据不同的优先级分配方法,基于优先级的调度算法可以分为如下两种类型[Krishna01][Wang99]:

静态优先级调度算法:

这种调度算法给那些系统中得到运行的所有进程都静态地分配一个优先级。静态优先级的分配可以根据应用的属性来进行,比如任务的周期,用户优先级,或者其它的预先确定的策略。RM(Rate-Monotonic)调度算法是一种典型的静态优先级调度算法,它根据任务的执行周期的长短来决定调度优先级,那些具有小的执行周期的任务具有较高的优先级。

动态优先级调度算法:

这种调度算法根据任务的资源需求来动态地分配任务的优先级,其目的就是在资源分配和调度时有更大的灵活性。非实时系统中就有很多这种调度算法,比如短作业优先的调度算法。在实时调度算法中, EDF算法是使用最多的一种动态优先级调度算法,该算法给就绪队列中的各个任务根据它们的截止期限(Deadline)来分配优先级,具有最近的截止期限的任务具有最高的优先级。

1.2. 基于比例共享调度算法

虽然基于优先级的调度算法简单而有效,但这种调度算法提供的是一种硬实时的调度,在很多情况下并不适合使用这种调度算法:比如象实时多媒体会议系统这样的软实时应用。对于这种软实时应用,使用一种比例共享式的资源调度算法(SD算法)更为适合。

比例共享调度算法指基于CPU使用比例的共享式的调度算法,其基本思想就是按照一定的权重(比例)对一组需要调度的任务进行调度,让它们的执行时间与它们的权重完全成正比。

我们可以通过两种方法来实现比例共享调度算法[Nieh01]:第一种方法是调节各个就绪进程出现在调度队列队首的频率,并调度队首的进程执行;第二种做法就是逐次调度就绪队列中的各个进程投入运行,但根据分配的权重调节分配个每个进程的运行时间片。

比例共享调度算法可以分为以下几个类别:轮转法、公平共享、公平队列、彩票调度法(Lottery)等。

比例共享调度算法的一个问题就是它没有定义任何优先级的概念;所有的任务都根据它们申请的比例共享CPU资源,当系统处于过载状态时,所有的任务的执行都会按比例地变慢。所以为了保证系统中实时进程能够获得一定的CPU处理时间,一般采用一种动态调节进程权重的方法。

1.3. 基于时间的进程调度算法

对于那些具有稳定、已知输入的简单系统,可以使用时间驱动(Time-driven:TD)的调度算法,它能够为数据处理提供很好的预测性。这种调度算法本质上是一种设计时就确定下来的离线的静态调度方法。在系统的设计阶段,在明确系统中所有的处理情况下,对于各个任务的开始、切换、以及结束时间等就事先做出明确的安排和设计。这种调度算法适合于那些很小的嵌入式系统、自控系统、传感器等应用环境。

这种调度算法的优点是任务的执行有很好的可预测性,但最大的缺点是缺乏灵活性,并且会出现有任务需要被执行而CPU却保持空闲的情况。

2. 通用Linux系统中的CPU调度

通用Linux系统支持实时和非实时两种进程,实时进程相对于普通进程具有绝对的优先级。对应地,实时进程采用SCHED_FIFO或者SCHED_RR调度策略,普通的进程采用SCHED_OTHER调度策略。

在调度算法的实现上,Linux中的每个任务有四个与调度相关的参数,它们是rt_priority、policy、priority(nice)、counter。调度程序根据这四个参数进行进程调度。

在SCHED_OTHER 调度策略中,调度器总是选择那个priority+counter值最大的进程来调度执行。从逻辑上分析,SCHED_OTHER调度策略存在着调度周期(epoch),在每一个调度周期中,一个进程的priority和counter值的大小影响了当前时刻应该调度哪一个进程来执行,其中 priority是一个固定不变的值,在进程创建时就已经确定,它代表了该进程的优先级,也代表这该进程在每一个调度周期中能够得到的时间片的多少; counter是一个动态变化的值,它反映了一个进程在当前的调度周期中还剩下的时间片。在每一个调度周期的开始,priority的值被赋给 counter,然后每次该进程被调度执行时,counter值都减少。当counter值为零时,该进程用完自己在本调度周期中的时间片,不再参与本调度周期的进程调度。当所有进程的时间片都用完时,一个调度周期结束,然后周而复始。另外可以看出Linux系统中的调度周期不是静态的,它是一个动态变化的量,比如处于可运行状态的进程的多少和它们priority值都可以影响一个epoch的长短。值得注意的一点是,在2.4以上的内核中, priority被nice所取代,但二者作用类似。

可见SCHED_OTHER调度策略本质上是一种比例共享的调度策略,它的这种设计方法能够保证进程调度时的公平性--一个低优先级的进程在每一个epoch中也会得到自己应得的那些CPU执行时间,另外它也提供了不同进程的优先级区分,具有高priority值的进程能够获得更多的执行时间。

对于实时进程来说,它们使用的是基于实时优先级rt_priority的优先级调度策略,但根据不同的调度策略,同一实时优先级的进程之间的调度方法有所不同:

SCHED_FIFO:不同的进程根据静态优先级进行排队,然后在同一优先级的队列中,谁先准备好运行就先调度谁,并且正在运行的进程不会被终止直到以下情况发生:1.被有更高优先级的进程所强占CPU;2.自己因为资源请求而阻塞;3.自己主动放弃CPU(调用sched_yield);

SCHED_RR:这种调度策略跟上面的SCHED_FIFO一模一样,除了它给每个进程分配一个时间片,时间片到了正在执行的进程就放弃执行;时间片的长度可以通过sched_rr_get_interval调用得到;

由于Linux系统本身是一个面向桌面的系统,所以将它应用于实时应用中时存在如下的一些问题:

Linux系统中的调度单位为10ms,所以它不能够提供精确的定时;

当一个进程调用系统调用进入内核态运行时,它是不可被抢占的;

Linux内核实现中使用了大量的封中断操作会造成中断的丢失;

由于使用虚拟内存技术,当发生页出错时,需要从硬盘中读取交换数据,但硬盘读写由于存储位置的随机性会导致随机的读写时间,这在某些情况下会影响一些实时任务的截止期限;

虽然Linux进程调度也支持实时优先级,但缺乏有效的实时任务的调度机制和调度算法;它的网络子系统的协议处理和其它设备的中断处理都没有与它对应的进程的调度关联起来,并且它们自身也没有明确的调度机制;

3. 各种实时Linux系统

3.1. RT-Linux和RTAI

RT -Linux是新墨西哥科技大学(New Mexico Institute of Technology)的研究成果[RTLinuxWeb][Barabanov97]。它的基本思想是,为了在Linux系统中提供对于硬实时的支持,它实现了一个微内核的小的实时操作系统(我们也称之为RT-Linux的实时子系统),而将普通Linux系统作为一个该操作系统中的一个低优先级的任务来运行。另外普通Linux系统中的任务可以通过FIFO和实时任务进行通信。RT-Linux的框架如图 1所示:

图 1 RT-Linux结构

RT -Linux的关键技术是通过软件来模拟硬件的中断控制器。当Linux系统要封锁CPU的中断时时,RT-Linux中的实时子系统会截取到这个请求,把它记录下来,而实际上并不真正封锁硬件中断,这样就避免了由于封中断所造成的系统在一段时间没有响应的情况,从而提高了实时性。当有硬件中断到来时, RT-Linux截取该中断,并判断是否有实时子系统中的中断例程来处理还是传递给普通的Linux内核进行处理。另外,普通Linux系统中的最小定时精度由系统中的实时时钟的频率决定,一般Linux系统将该时钟设置为每秒来100个时钟中断,所以Linux系统中一般的定时精度为 10ms,即时钟周期是10ms,而RT-Linux通过将系统的实时时钟设置为单次触发状态,可以提供十几个微秒级的调度粒度。

RT-Linux实时子系统中的任务调度可以采用RM、EDF等优先级驱动的算法,也可以采用其他调度算法。

RT -Linux对于那些在重负荷下工作的专有系统来说,确实是一个不错的选择,但他仅仅提供了对于CPU资源的调度;并且实时系统和普通Linux系统关系不是十分密切,这样的话,开发人员不能充分利用Linux系统中已经实现的功能,如协议栈等。所以RT-Linux适合与工业控制等实时任务功能简单,并且有硬实时要求的环境中,但如果要应用与多媒体处理中还需要做大量的工作。

意大利的RTAI( Real-Time Application Interface )源于RT-Linux,它在设计思想上和RT-Linux完全相同。它当初设计目的是为了解决RT-Linux难于在不同Linux版本之间难于移植的问题,为此,RTAI在 Linux 上定义了一个实时硬件抽象层,实时任务通过这个抽象层提供的接口和Linux系统进行交互,这样在给Linux内核中增加实时支持时可以尽可能少地修改 Linux的内核源代码。

3.2. Kurt-Linux

Kurt -Linux由Kansas大学开发,它可以提供微秒级的实时精度[KurtWeb] [Srinivasan]。不同于RT-Linux单独实现一个实时内核的做法,Kurt -Linux是在通用Linux系统的基础上实现的,它也是第一个可以使用普通Linux系统调用的基于Linux的实时系统。

Kurt-Linux将系统分为三种状态:正常态、实时态和混合态,在正常态时它采用普通的Linux的调度策略,在实时态只运行实时任务,在混合态实时和非实时任务都可以执行;实时态可以用于对于实时性要求比较严格的情况。

为了提高Linux系统的实时特性,必须提高系统所支持的时钟精度。但如果仅仅简单地提高时钟频率,会引起调度负载的增加,从而严重降低系统的性能。为了解决这个矛盾, Kurt-Linux采用UTIME所使用的提高Linux系统中的时钟精度的方法[UTIMEWeb]:它将时钟芯片设置为单次触发状态(One shot mode),即每次给时钟芯片设置一个超时时间,然后到该超时事件发生时在时钟中断处理程序中再次根据需要给时钟芯片设置一个超时时间。它的基本思想是一个精确的定时意味着我们需要时钟中断在我们需要的一个比较精确的时间发生,但并非一定需要系统时钟频率达到此精度。它利用CPU的时钟计数器TSC (Time Stamp Counter)来提供精度可达CPU主频的时间精度。

对于实时任务的调度,Kurt-Linux采用基于时间(TD)的静态的实时CPU调度算法。实时任务在设计阶段就需要明确地说明它们实时事件要发生的时间。这种调度算法对于那些循环执行的任务能够取得较好的调度效果。

Kurt -Linux相对于RT-Linux的一个优点就是可以使用Linux系统自身的系统调用,它本来被设计用于提供对硬实时的支持,但由于它在实现上只是简单的将Linux调度器用一个简单的时间驱动的调度器所取代,所以它的实时进程的调度很容易受到其它非实时任务的影响,从而在有的情况下会发生实时任务的截止期限不能满足的情况,所以也被称作严格实时系统(Firm Real-time)。目前基于Kurt-Linux的应用有:ARTS(ATM Reference Traffic System)、多媒体播放软件等。另外Kurt-Linux所采用的这种方法需要频繁地对时钟芯片进行编程设置。

3.3. RED-Linux

RED -Linux是加州大学Irvine分校开发的实时Linux系统[REDWeb][ Wang99],它将对实时调度的支持和Linux很好地实现在同一个操作系统内核中。它同时支持三种类型的调度算法,即:Time-Driven、 Priority-Dirven、Share-Driven。

为了提高系统的调度粒度,RED-Linux从RT-Linux那儿借鉴了软件模拟中断管理器的机制,并且提高了时钟中断频率。当有硬件中断到来时,RED-Linux的中断模拟程序仅仅是简单地将到来的中断放到一个队列中进行排队,并不执行真正的中断处理程序。

另外为了解决Linux进程在内核态不能被抢占的问题, RED-Linux在Linux内核的很多函数中插入了抢占点原语,使得进程在内核态时,也可以在一定程度上被抢占。通过这种方法提高了内核的实时特性。

RED-Linux的设计目标就是提供一个可以支持各种调度算法的通用的调度框架,该系统给每个任务增加了如下几项属性,并将它们作为进程调度的依据:

Priority:作业的优先级;

Start-Time:作业的开始时间;

Finish-Time:作业的结束时间;

Budget:作业在运行期间所要使用的资源的多少;

通过调整这些属性的取值及调度程序按照什么样的优先顺序来使用这些属性值,几乎可以实现所有的调度算法。这样的话,可以将三种不同的调度算法无缝、统一地结合到了一起。

㈣ 从2.x到4.x,Linux内核这十年经历了哪些重要变革

Linux内核现在已经进入4.x时代了,但是据说从版本2.6升到3.0,以及3.19升到4.0这之间都没什么太大的变革。事实如此吗?内核版本间的区别有多大?
说实话,这个问题挺大的。Linux内核的2.6 时代跨度非常大,从2.6.1 (2003年12月发布) 到 2.6.39(2011年5月发布),跨越了39 个大版本。3.0(原计划的2.6.40,2011年7月发布) 到 3.19(2015年2月发布),经历了20个版本。4.0(2015年4月发布)到4.2(2015年8月底发布),又有3个版本。
总的来说,从进入2.6之后,每个大版本跨度开发时间大概是 2 - 3 个月。2.6.x , 3.x, 4.x,数字的递进并没有非常根本性,引人注目的大变化,但每个大版本中都有一些或大或小的功能改变。主版本号只是一个数字而已。不过要直接从 2.6.x 升级 到 3.x, 乃至 4.x,随着时间间隔增大,出问题的机率当然大很多。
个人觉得 Linux 真正走入严肃级别的高稳定性,高可用性,高可伸缩性的工业级别内核大概是在 2003 年之后吧!一是随着互联网的迅速普及,更多的人使用、参与开发。二是社区经过11年发展,已经慢慢摸索出一套很稳定的协同开发模式,一个重要的特点是社区 开始使用版本管理工具进行管理,脱离了之前纯粹手工(或一些辅助的简陋工具)处理代码邮件的方式,大大加快了开发的速度和力度。
因此,本文汇总分析一下从 2.6.12 (2005年6月发布,也就是社区开始使用 git 进行管理后的第一个大版本),到 4.2 (2015年8月发布)这中间共 51个大版本 ,时间跨度 10年 的主要大模块的一些重要的变革。
1.抢占支持(preemption): 2.6 时代开始支持(具体时间难考,是在 2.5 这个奇数版本中引入,可看此文章[1],关于 Linux 版本规则,可看我文章[2])。
可抢占性,对一个系统的调度延时具有重要意义。2.6 之前,一个进程进入内核态后,别的进程无法抢占,只能等其完成或退出内核态时才能抢占,这带来严重的延时问题,2.6 开始支持内核态抢占。
2.普通进程调度器(SCHED_OTHER)之纠结进化史
Linux一开始,普通进程和实时进程都是基于优先级的一个调度器,实时进程支持 100 个优先级,普通进程是优先级小于实时进程的一个静态优先级,所有普通进程创建时都是默认此优先级,但可通过 nice() 接口调整动态优先级(共40个)。实时进程的调度器比较简单,而普通进程的调度器,则历经变迁[3]:
(1) O(1) 调度器:2.6 时代开始支持(2002年引入)。顾名思义,此调度器为O(1)时间复杂度。该调度器以修正之间的O(n) 时间复杂度调度器,以解决扩展性问题。为每一个动态优先级维护队列,从而能在常数时间内选举下一个进程来执行。

㈤ 在 2.4 版本的 linux 内核中,内核任务可以被抢占吗

UNIX采用抢占式内核,Linux采用非抢占式内核
内核抢占(可抢占式内核):即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程。

非抢占式内核:高优先级的进程不能中止正在内核中运行的低优先级的进程而抢占CPU运行。进程一旦处于核心态(例如用户进程执行系统调用),则除非进程自愿放弃CPU,否则该进程将一直运行下去,直至完成或退出内核

抢占式内核的意义:首先,这是将Linux应用于实时系统所必需的。实时系统对响应时间有严格的限定,当一个实时进程被实时设备的硬件中断唤醒后,它应在限定的时间内被调度执行。而Linux不能满足这一要求,因为Linux的内核是不可抢占的,不能确定系统在内核中的停留时间。事实上当内核执行长的系统调用时,实时进程要等到内核中运行的进程退出内核才能被调度,由此产生的响应延迟,在如今的硬件条件下,会长达100ms级。这对于那些要求高实时响应的系统是不能接受的。而可抢占的内核不仅对Linux的实时应用至关重要,而且能解决Linux对多媒体(video, audio)等要求低延迟的应用支持不够好的缺陷。

㈥ linux进程调度的三种策略是什么

linux内核的三种主要调度策略:
1,SCHED_OTHER 分时调度策略,
2,SCHED_FIFO实时调度策略,先到先服务
3,SCHED_RR实时调度策略,时间片轮转

实时进程将得到优先调用,实时进程根据实时优先级决定调度权值。分时进程则通过nice和counter值决定权值,nice越小,counter越大,被调度的概率越大,也就是曾经使用了cpu最少的进程将会得到优先调度。

SHCED_RR和SCHED_FIFO的不同:
当采用SHCED_RR策略的进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。
SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。
如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO时必须等待该进程主动放弃后才可以运行这个优先级相同的任务。而RR可以让每个任务都执行一段时间。

相同点:
RR和FIFO都只用于实时任务。
创建时优先级大于0(1-99)。
按照可抢占优先级调度算法进行。
就绪态的实时任务立即抢占非实时任务。

所有任务都采用linux分时调度策略时:
1,创建任务指定采用分时调度策略,并指定优先级nice值(-20~19)。
2,将根据每个任务的nice值确定在cpu上的执行时间(counter)。
3,如果没有等待资源,则将该任务加入到就绪队列中。
4,调度程序遍历就绪队列中的任务,通过对每个任务动态优先级的计算权值(counter+20-nice)结果,选择计算结果最大的一个去运行,当这个时间片用完后(counter减至0)或者主动放弃cpu时,该任务将被放在就绪队列末尾(时间片用完)或等待队列(因等待资源而放弃cpu)中。
5,此时调度程序重复上面计算过程,转到第4步。
6,当调度程序发现所有就绪任务计算所得的权值都为不大于0时,重复第2步。

所有任务都采用FIFO时:
1,创建进程时指定采用FIFO,并设置实时优先级rt_priority(1-99)。
2,如果没有等待资源,则将该任务加入到就绪队列中。
3,调度程序遍历就绪队列,根据实时优先级计算调度权值(1000+rt_priority),选择权值最高的任务使用cpu,该FIFO任务将一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)。
4,调度程序发现有优先级更高的任务到达(高优先级任务可能被中断或定时器任务唤醒,再或被当前运行的任务唤醒,等等),则调度程序立即在当前任务堆栈中保存当前cpu寄存器的所有数据,重新从高优先级任务的堆栈中加载寄存器数据到cpu,此时高优先级的任务开始运行。重复第3步。
5,如果当前任务因等待资源而主动放弃cpu使用权,则该任务将从就绪队列中删除,加入等待队列,此时重复第3步。

所有任务都采用RR调度策略时:
1,创建任务时指定调度参数为RR,并设置任务的实时优先级和nice值(nice值将会转换为该任务的时间片的长度)。
2,如果没有等待资源,则将该任务加入到就绪队列中。
3,调度程序遍历就绪队列,根据实时优先级计算调度权值(1000+rt_priority),选择权值最高的任务使用cpu。
4,如果就绪队列中的RR任务时间片为0,则会根据nice值设置该任务的时间片,同时将该任务放入就绪队列的末尾。重复步骤3。
5,当前任务由于等待资源而主动退出cpu,则其加入等待队列中。重复步骤3。

系统中既有分时调度,又有时间片轮转调度和先进先出调度:
1,RR调度和FIFO调度的进程属于实时进程,以分时调度的进程是非实时进程。
2,当实时进程准备就绪后,如果当前cpu正在运行非实时进程,则实时进程立即抢占非实时进程。
3,RR进程和FIFO进程都采用实时优先级做为调度的权值标准,RR是FIFO的一个延伸。FIFO时,如果两个进程的优先级一样,则这两个优先级一样的进程具体执行哪一个是由其在队列中的未知决定的,这样导致一些不公正性(优先级是一样的,为什么要让你一直运行?),如果将两个优先级一样的任务的调度策略都设为RR,则保证了这两个任务可以循环执行,保证了公平。

Ingo Molnar-实时补丁
为了能并入主流内核,Ingo Molnar的实时补丁也采用了非常灵活的策略,它支持四种抢占模式:
1.No Forced Preemption (Server),这种模式等同于没有使能抢占选项的标准内核,主要适用于科学计算等服务器环境。
2.Voluntary Kernel Preemption (Desktop),这种模式使能了自愿抢占,但仍然失效抢占内核选项,它通过增加抢占点缩减了抢占延迟,因此适用于一些需要较好的响应性的环境,如桌面环境,当然这种好的响应性是以牺牲一些吞吐率为代价的。
3.Preemptible Kernel (Low-Latency Desktop),这种模式既包含了自愿抢占,又使能了可抢占内核选项,因此有很好的响应延迟,实际上在一定程度上已经达到了软实时性。它主要适用于桌面和一些嵌入式系统,但是吞吐率比模式2更低。
4.Complete Preemption (Real-Time),这种模式使能了所有实时功能,因此完全能够满足软实时需求,它适用于延迟要求为100微秒或稍低的实时系统。
实现实时是以牺牲系统的吞吐率为代价的,因此实时性越好,系统吞吐率就越低。

㈦ Linux内核设计与实现的目录

译者序
序言
前言
作者简介
第1章Linux内核简介1
1.1Unix的历史1
1.2追寻Linus足迹:Linux简介2
1.3操作系统和内核简介3
1.4Linux内核和传统Unix内核的比较5
1.5Linux内核版本7
1.6Linux内核开发者社区8
1.7小结8
第2章从内核出发10
2.1获取内核源码10
2.1.1使用Git10
2.1.1安装内核源代码10
2.1.3使用补丁11
2.2内核源码树11
2.3编译内核12
2.3.1配置内核12
2.3.2减少编译的垃圾信息14
2.3.3衍生多个编译作业 14
2.3.4安装新内核14
2.4内核开发的特点15
2.4.1无libc库抑或无标准头文件15
2.4.2GNU C16
2.4.3没有内存保护机制18
2.4.4不要轻易在内核中使用浮点数18
2.4.5容积小而固定的栈18
2.4.6同步和并发18
2.4.7可移植性的重要性19
2.5小结19
第3章进程管理20
3.1进程20
3.2进程描述符及任务结构 21
3.2.1分配进程描述符22
3.2.2进程描述符的存放23
3.2.3进程状态23
3.2.4设置当前进程状态25
3.2.5进程上下文25
3.2.6进程家族树25
3.3进程创建26
3.3.1写时拷贝27
3.3.2fork()27
3.3.3vfork()28
3.4线程在Linux中的实现28
3.4.1创建线程29
3.4.2内核线程30
3.5进程终结31
3.5.1删除进程描述符32
3.5.2孤儿进程造成的进退维谷32
3.6小结34
第4章进程调度35
4.1多任务35
4.2Linux 的进程调度36
4.3策略36
4.3.1I/O消耗型和处理器消耗型的进程36
4.3.2进程优先级37
4.3.3时间片38
4.3.4调度策略的活动38
4.4Linux调度算法39
4.4.1调度器类39
4.4.2Unix 系统中的进程调度40
4.4.3公平调度41
4.5Linux调度的实现42
4.5.1时间记账42
4.5.2进程选择44
4.5.3调度器入口48
4.5.4睡眠和唤醒49
4.6抢占和上下文切换51
4.6.1用户抢占53
4.6.2内核抢占53
4.7实时调度策略54
4.8与调度相关的系统调用54
4.8.1与调度策略和优先级相关的系统调用55
4.8.2与处理器绑定有关的系统调用55
4.8.3放弃处理器时间56
4.9小结56
第5章系统调用57
5.1与内核通信57
5.2API、POSIX和C库57
5.3系统调用58
5.3.1系统调用号59
5.3.2系统调用的性能59
5.4系统调用处理程序60
5.4.1指定恰当的系统调用60
5.4.2参数传递60
5.5系统调用的实现61
5.5.1实现系统调用61
5.5.2参数验证62
5.6系统调用上下文64
5.6.1绑定一个系统调用的最后步骤65
5.6.2从用户空间访问系统调用67
5.6.3为什么不通过系统调用的方式实现68
5.7小结68
第6章内核数据结构69
6.1链表69
6.1.1单向链表和双向链表69
6.1.2环形链表70
6.1.3沿链表移动71
6.1.4Linux 内核中的实现71
6.1.5操作链表73
6.1.6遍历链表75
6.2队列78
6.2.1kfifo79
6.2.2创建队列79
6.2.3推入队列数据79
6.2.4摘取队列数据80
6.2.5获取队列长度80
6.2.6重置和撤销队列80
6.2.7队列使用举例 81
6.3映射 81
6.3.1初始化一个idr82
6.3.2分配一个新的UID82
6.3.3查找UID83
6.3.4删除UID84
6.3.5撤销idr84
6.4二叉树84
6.4.1二叉搜索树84
6.4.2自平衡二叉搜索树 85
6.5数据结构以及选择 87
6.6算法复杂度88
6.6.1算法88
6.6.2大o 符号88
6.6.3大θ符号89
6.6.4时间复杂度89
6.7小结 90
第7章中断和中断处理91
7.1中断91
7.2中断处理程序92
7.3上半部与下半部的对比93
7.4注册中断处理程序93
7.4.1中断处理程序标志94
7.4.2一个中断例子95
7.4.3释放中断处理程序95
7.5编写中断处理程序96
7.5.1共享的中断处理程序97
7.5.2中断处理程序实例97
7.6中断上下文99
7.7中断处理机制的实现100
7.8/proc/interrupts102
7.9中断控制103
7.9.1禁止和激活中断103
7.9.2禁止指定中断线105
7.9.3中断系统的状态105
7.10小结106
第8章下半部和推后执行的工作107
8.1下半部107
8.1.1为什么要用下半部108
8.1.2下半部的环境108
8.2软中断110
8.2.1软中断的实现111
8.2.2使用软中断113
8.3tasklet114
8.3.1tasklet的实现114
8.3.2使用tasklet116
8.3.3老的BH机制119
8.4工作队列120
8.4.1工作队列的实现121
8.4.2使用工作队列124
8.4.3老的任务队列机制126
8.5下半部机制的选择127
8.6在下半部之间加锁128
8.7禁止下半部128
8.8小结129
第9章内核同步介绍131
9.1临界区和竞争条件131
9.1.1为什么我们需要保护132
9.1.2单个变量133
9.2加锁134
9.2.1造成并发执行的原因135
9.2.2了解要保护些什么136
9.3死锁137
9.4争用和扩展性138
9.5小结140
第10章内核同步方法141
10.1原子操作141
10.1.1原子整数操作142
10.1.264位原子操作144
10.1.3原子位操作145
10.2自旋锁147
10.2.1自旋锁方法148
10.2.2其他针对自旋锁的操作149
10.2.3自旋锁和下半部150
10.3读-写自旋锁150
10.4信号量152
10.4.1计数信号量和二值信号量153
10.4.2创建和初始化信号量154
10.4.3使用信号量154
10.5读-写信号量155
10.6互斥体156
10.6.1信号量和互斥体158
10.6.2自旋锁和互斥体158
10.7完成变量158
10.8BLK:大内核锁159
10.9顺序锁160
10.10禁止抢占161
10.11顺序和屏障162
10.12小结165
第11章定时器和时间管理166
11.1内核中的时间概念166
11.2节拍率:HZ167
11.2.1理想的HZ值168
11.2.2高HZ的优势169
11.2.3高HZ的劣势169
11.3jiffies170
11.3.1jiffies的内部表示171
11.3.2jiffies 的回绕172
11.3.3用户空间和HZ173
11.4硬时钟和定时器174
11.4.1实时时钟174
11.4.2系统定时器174
11.5时钟中断处理程序174
11.6实际时间176
11.7定时器178
11.7.1使用定时器178
11.7.2定时器竞争条件180
11.7.3实现定时器180
11.8延迟执行181
11.8.1忙等待181
11.8.2短延迟182
11.8.3schele_timeout()183
11.9小结185
第12章内存管理186
12.1页186
12.2区187
12.3获得页189
12.3.1获得填充为0的页190
12.3.2释放页191
12.4kmalloc()191
12.4.1gfp_mask标志192
12.4.2kfree()195
12.5vmalloc()196
12.6slab层197
12.6.1slab层的设计198
12.6.2slab分配器的接口200
12.7在栈上的静态分配203
12.7.1单页内核栈203
12.7.2在栈上光明正大地工作203
12.8高端内存的映射204
12.8.1永久映射204
12.8.2临时映射204
12.9每个CPU的分配20512.10新的每个CPU接口206
12.10.1编译时的每个CPU数据206
12.10.2运行时的每个CPU数据207
12.11使用每个CPU数据的原因208
12.12分配函数的选择209
12.13小结209
第13章虚拟文件系统210
13.1通用文件系统接口210
13.2文件系统抽象层211
13.3Unix文件系统212
13.4VFS 对象及其数据结构213
13.5超级块对象214
13.6超级块操作215
13.7索引节点对象217
13.8索引节点操作219
13.9目录项对象222
13.9.1目录项状态222
13.9.2目录项缓存223
13.10目录项操作224
13.11文件对象225
13.12文件操作226
13.13和文件系统相关的数据结构230
13.14和进程相关的数据结构232
13.15小结233
第14章块I/O层234
14.1剖析一个块设备234
14.2缓冲区和缓冲区头235
14.3bio结构体237
14.3.1I/O向量238
14.3.2新老方法对比239
14.4请求队列240
14.5I/O调度程序240
14.5.1I/O调度程序的工作241
14.5.2Linus 电梯241
14.5.3最终期限I/O调度程序242
14.5.4预测I/O调度程序244
14.5.5完全公正的排队I/O调度程序244
14.5.6空操作的I/O调度程序245
14.5.7I/O调度程序的选择245
14.6小结246
第15章进程地址空间247
15.1地址空间247
15.2内存描述符248
15.2.1分配内存描述符249
15.2.2撤销内存描述符250
15.2.3mm_struct 与内核线程250
15.3虚拟内存区域251
15.3.1VMA标志251
15.3.2VMA 操作253
15.3.3内存区域的树型结构和内存区域的链表结构254
15.3.4实际使用中的内存区域254
15.4操作内存区域255
15.4.1find_vma()256
15.4.2find_vma_prev()257
15.4.3find_vma_intersection()257
15.5mmap()和do_mmap():创建地址区间258
15.6mummap()和do_mummap():删除地址区间259
15.7页表260
15.8小结261
第16章页高速缓存和页回写262
16.1缓存手段262
16.1.1写缓存262
16.1.2缓存回收263
16.2Linux 页高速缓存264
16.2.1address_space对象264
16.2.2address_space 操作266
16.2.3基树267
16.2.4以前的页散列表268
16.3缓冲区高速缓存268
16.4flusher线程268
16.4.1膝上型计算机模式270
16.4.2历史上的bdflush、kupdated 和pdflush270
16.4.3避免拥塞的方法:使用多线程271
16.5小结271
第17章设备与模块273
17.1设备类型273
17.2模块274
17.2.1Hello,World274
17.2.2构建模块275
17.2.3安装模块277
17.2.4产生模块依赖性277
17.2.5载入模块278
17.2.6管理配置选项279
17.2.7模块参数280
17.2.8导出符号表282
17.3设备模型283
17.3.1kobject283
17.3.2ktype284
17.3.3kset285
17.3.4kobject、ktype和kset的相互关系285
17.3.5管理和操作kobject286
17.3.6引用计数287
17.4sysfs288
17.4.1sysfs中添加和删除kobject 290
17.4.2向sysfs中添加文件291
17.4.3内核事件层293
17.5小结294
第18章调试295
18.1准备开始295
18.2内核中的bug296
18.3通过打印来调试296
18.3.1健壮性296
18.3.2日志等级297
18.3.3记录缓冲区298
18.3.4syslogd和klogd298
18.3.5从printf()到printk()的转换298
18.4oops298
18.4.1ksymoops300
18.4.2kallsyms300
18.5内核调试配置选项301
18.6引发bug并打印信息301
18.7神奇的系统请求键302
18.8内核调试器的传奇303
18.8.1gdb303
18.8.2kgdb304
18.9探测系统304
18.9.1用UID作为选择条件304
18.9.2使用条件变量305
18.9.3使用统计量305
18.9.4重复频率限制305
18.10用二分查找法找出引发罪恶的变更306
18.11使用Git进行二分搜索307
18.12当所有的努力都失败时:社区308
18.13小结308
第19章可移植性309
19.1可移植操作系统309
19.2Linux移植史310
19.3字长和数据类型311
19.3.1不透明类型313
19.3.2指定数据类型314
19.3.3长度明确的类型314
19.3.4char型的符号问题315
19.4数据对齐315
19.4.1避免对齐引发的问题316
19.4.2非标准类型的对齐316
19.4.3结构体填补316
19.5字节顺序318
19.6时间319
19.7页长度320
19.8处理器排序320
19.9SMP、内核抢占、高端内存321
19.10小结321
第20章补丁、开发和社区322
20.1社区322
20.2Linux编码风格322
20.2.1缩进323
20.2.2switch 语句323
20.2.3空格324
20.2.4花括号325
20.2.5每行代码的长度326
20.2.6命名规范326
20.2.7函数326
20.2.8注释326
20.2.9typedef327
20.2.10多用现成的东西328
20.2.11在源码中减少使用ifdef328
20.2.12结构初始化328
20.2.13代码的事后修正329
20.3管理系统329
20.4提交错误报告329
20.5补丁330
20.5.1创建补丁330
20.5.2用Git创建补丁331
20.5.3提交补丁331
20.6小结332
参考资料333

㈧ linux 多核使用什么内核锁

从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机版制的发展伴随权Linux从单处理器到对称多处理器的过渡;
伴随着从非抢占内核到抢占内核的过度。Linux的锁机制越来越有效,也越来越复杂。
Linux的内核锁主要是自旋锁和信号量。
自旋锁最多只能被一个可执行线程持有,如果一个执行线程试图请求一个已被争用(已经被持有)的自旋锁,那么这个线程就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求它的执行线程便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的执行线程同时进入临界区。
Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。

㈨ linux内核:异步中断,抢占及SMP都是什么意思

异步中断就是中断的中断源不是当前进程,其实硬件中断都是异步的。

抢占是指高优先级的进程可以强占低优先级的进程的运行资源。

SMP,是对称多处理的意思,就是几个CPU核心对于内存来讲是地位相同的,没有主次之分

阅读全文

与禁止linux内核抢占相关的资料

热点内容
iphone5c日版九宫格 浏览:628
西门子300控制伺服电机如何编程 浏览:94
复制文件慢win10 浏览:523
数据如何分段为中间多两边少 浏览:181
暨阳论坛怎么升级 浏览:181
今日头条如何导出数据 浏览:518
outlook无法创建工作文件夹 浏览:529
数控机床编程中产品倒角怎么编程 浏览:914
word2016恢复asd文件 浏览:435
zip压缩如何更改文件名 浏览:809
java调用c的类 浏览:928
微信分享开发教程 浏览:65
泰安网站制作公司怎么找 浏览:889
iphone6无法备份应用 浏览:650
百度云下载的文件在哪ipad 浏览:586
全球通58元套餐升级 浏览:976
音频文件加到word 浏览:572
表格数据如何整列求和 浏览:573
宽带升级外线 浏览:573
一根数据线多少钱oppo 浏览:622

友情链接