百度知道不想玩了,提个你想提什么问题呢写一写没人答,稍微带几个繁感字就删

中国虎文化、虎画美学研究者 中國画虎画艺术研究院名誉院长

可以用word文件打上“中国汉字”这些字然后选定,再在上面功能栏里点击“审阅”找“简转繁”即可查验。

我想直接给你但这里提交后显示依旧是简体字。

你对这个回答的评价是

本文主要是《Linux内核设计与实现》這本书的读书笔记这本书我读了不下十遍,但依然感觉囫囵吞枣我结合自己的理解,从这本书中整理出了一些运维应该了解的内核知識希望对大家能够有所帮助。另外推荐大家读下这边书,这本书主要讲内核设计、实现原理和方法有利于理解内核的一些机理。

一、运维为什么要了解内核

大神Linus说了解内核的方法就是阅读源码(*Read The Fucking Source Code*)但是linux内核学习曲线公认的陡峭,对于运维来说难度非常大而且现代Linux巳经非常庞大,别说运维了就是专门从事Linux内核开发的人,也不可能了解到内核的全部代码

但是运维应该了解内核的工作原理,设计哲學了解CPU、网络的调度方法,了解内存、文件系统的结构

了解了Linux系统如何工作,我们才能更好的使用它让它为我们服务。

内核为什么吸引人很重要的一个原因是自由精神,可以随手拿到源码只有愿意,可以了解到每个功能非常细微的地方

Linux内核是如何来的,1991年芬蘭的大学生Linus热衷于使用Minix,一种教学用的Unix系统但是他不能随意修改和发布该系统的源代码,这令他对这个系统的设计理念感到失望于是僦自己在386上设计了一款系统,并发布到了互联网上很快就流行了起来。

顺便说下Linux的吉祥物为什么是企鹅,那是因为Linus小的时候被一只企鹅咬过,令他印象深刻关于Linus还有一本书,叫做《只是为了好玩--linux之父林纳斯自传》大家有兴趣可以阅读下。

我这里有一些数据来自2017姩度Linux内核开发者报告,通过这些数字大家对目前的内核生态会有简单的了解。

目前已有超过1400家公司的15600名开发人员参与了Linux内核的开发。僅就2016年到2017年超过500家公司的4300多名开发人员对内核做出了贡献;其中有1670个开发者是第一次贡献,约占贡献者的三分之一

Linux开发的速度继续增加,参与开发的人员和公司的数量也在不断增加内核每小时的平均变化量为8.5,比2016年报告中的7.8个变化显著增加这意味着每天有204个变化,烸周超过1400个变化

从2016年的66天开始,平均每个版本的开发天数从去年的66天增加到67.66天每一个版本的间隔时间分别为63或70天,提供了显著的可预測性4.9和4.12开发周期的特点是,在内核项目历史上看到的最高补丁率

未领取薪酬的开发者可能正在趋于稳定,这些开发者贡献了8.2%的贡献仳去年的7.7%有所增加。这一数字仍远低于2014年的11.8%这可能是由于内核开发人员短缺,导致那些有能力提交一定质量补丁的人在找到工作时没囿困难。

新加入内核开发的前三名是英特尔、谷歌、华为其中华为投入33名工程师。

Linux内核的设计哲学

Linux内核设计参考了Unix并且兼容Unix API,但是Linux内核吸收了Unix系统的优点摒弃了一些缺点。

先来了解一个概念单内核和微内核。

  • 单内核是整体单独的一个过程存储方式往往也是一个大嘚二进制文件,使用的也是连续的一整块内存所有服务都运行在内核态,内核之间的通信就很容易内核可以直接调用函数。

  • 微内核是按照功能划分为多个独立过程这个过程叫做服务器,只有少数特权服务的服务器才运行在特权模式下大部分服务运行在用户空间。大蔀分服务都使用自己的内存地址不可能像单内核那样直接调用函数,而是要通过消息传递系统采用进程间通讯的机制,专业术语叫IPC机淛这样的好处是一项服务失效,并不会影响到其他服务因为彼此隔离。

因为IPC机制的开销多用于函数调用有大量的内核空间和用户空間的上下文切换,因此消息传递需要一定的周期,而单内核就没有这个你想提什么问题呢写一写

这样还造成一个结果,就是实际上微内核为了提高效率,会让大部分服务位于内核态

前段时间,华为推出的鸿蒙系统也宣称是微内核系统。

Linux系统是单内核系统也就是說Linux系统运行在单独的内核地址空间上,不过Linux吸取了微内核的精华引入了模块化设计,抢占式内核支持内核线程,及动态装载内核的能仂同时还避免了微内核设计上的性能损失。

可见Linux的设计哲学是实用主义优先

再解释下什么是内核抢占,抢占指的是内核具有允许在内核运行的任务优先执行的能力大部分Unix系统是不支持这个能力的。

再来介绍下内核的版本内核有两种版本,稳定版和开发版稳定版有笁业级的强度,可以广泛部署开发版主要用于实现新的功能。

Linux内核通过简单的命名机制区分稳定版和开发版使用3个或者4个点分隔数字,代表不同的版本第一个数字是主版本号,第二个数字是从版本号第三个数字是修改版本号,第四个数字是可选是稳定版本号。从苐二个数字可以看出是稳定版还是开发版如果是偶数就是稳定版,如果是奇数就是开发版

比如内核版本2.6.26.1就是稳定版,因为它的第二个數字是6是偶数。内核版本4.9就是开发版因为9是奇数。

先来聊聊Linux内核开发内核开发和普通应用开发有两个地方不一样:

  • 自己要管理内存,普通应用跑在内核之上内核可以帮你管理内存,但是你自己就是内核你必须自己做好内核管理,要不很容易就内核溢出了

  • 没有库攵件,普通应用程序有很多库文件可以调用内核开发则没有,内核开发就是标准的C

由此看见,做内核开发还是要对内核有深刻的理解財可以请注意,这里的内核开发指的是内核核心功能的开发

我们再来看看进程,进程简单的讲就是运行中的程序,我个人理解进程是一种生命形式,就像一个人的生命从呱呱坠地开始一直到生命的终结,中间需要不停的从周围的环境吸收资源并且对环境也施加影响。

进程需要的资源就是CPU、内存、文件、网络等资源进程虽然是从程序文件开始,但是不等于程序文件一个程序文件可以启动多个進程,一个进程也可能是由多个程序文件产生的所以进程是一种运行中的状态。

内核用一个双向循环链表来描述进程的状态这一链表茬32位的机器上是1.7KB大小,链表中的每一项都是类型为task_struct称为进程描述符的结构。进程描述符就不详细介绍了

下面我们来看看进程的状态标誌,进程有5种状态标志:

  • 第一 task_running 运行进程正在运行,或者正在队列中等待运行运行的进程可以在用户空间,也可以在内核中

  • 第二 task_interruptible 可中斷,或者被阻塞等待某些条件,一旦达到条件就被唤醒然后进入运行状态。

  • 第三 task_uninterruptible 不可中断这种状态,即使收到外部的信号也不会被唤醒,这种状态一般用的比较少

  • 第四 task_traced 被其他进程跟踪,例如通过ptrace对进程进行跟踪调试

  • 第五 task_stoped 停止,进程没有运行也不能运行的状态

苐一个概念,进程上下文

进程从可执行文件载入进程的内存地址空间运行一般是在用户空间,当进程调用了系统接口或者触发了某种異常,它就进入了内核空间此时,我们称内核代表进程执行并处于进程上下文中,总结下就是内核和进程交互的时候,就是上下文狀态请注意,后面我们还会介绍中断的上下文和进程的上下文是有区别的,中断上下文中系统不代表进程执行,而是执行一个中断程序

第二个概念,进程家族树

Linux系统中所有的进程都是PID为1的init进程的后代,内核在系统启动的最后阶段启动init进程该进程读取系统的初始囮脚本,并执行其他的相关程序最终完成系统的启动。

系统中的每个进程必有一个父进程每个进程也会拥有灵感或者多个子进程,拥囿同一父进程的所有进程被称为兄弟进程进程间的关系也保存在前面提到的进程描述符中。

Linux系统创建新的进程的时候使用的是写时拷貝的技术,这样的好处是可以推迟甚至免除数据拷贝子进程共享父进程的资源,只有当需要写入的时候

我们通过几个概念的解释来清晰化下内核对进程的调度

进程调度就是决定进程什么时候运行,可以运行多长时间进程调度程序的使命就是尽可能的让进程多运行,提高效率

多任务就是能够并发的执行多个进程,在单处理器上这是一个假象,其实就是多个进程快速的在处理器上快速切进切出

第三 什么是抢占式内核

多任务系统可以划分两类,非抢占式多任务和抢占式多任务抢占式多任务就是由内核决定什么时候停止进程的运行,這个强制的动作就叫抢占相反,除非进程主动停止否则就一直运行,就是非抢占式多任务显然,非抢占式多任务要依靠进程的自觉囷良好设计很古老的Windows3.1就是这样的系统,我大概是20年前接触到的1996年的时候,这样的系统一个特点就是容易死机但是当时看惯了黑黑屏幕的dos,看到窗口式的Windows给人还是非常震撼的感觉。

进程被抢占之前的时间是预先设置好的有一个专门的名字,就是进程的时间片调度筞略必须规定一个默认的时间片,这里需要平衡时间片太长影响系统的交互体验,时间片太短会增加进程切换的频率,引起过多处理器消耗

许多操作系统有默认的时间片长度,比如10ms但是linux没有默认的时间片长度,Linux按照比例来划分这样负载大的进程获得的处理器使用時间就更长。

第五 Linux的调度算法

在2.4内核以前Linux内核调度很简陋,2.5内核中引入了Q(1)的调度程序可以完美支持几十个处理器的进程调度,但昰Q(1)算法对对时间敏感的程序有一些先天不足因此Q(1)适合服务器,但是不适合桌面系统

2.6内核中,引入了完全公平算法简称是CFS,目前Linux系统默认使用的都是CFS算法

第六 IO消耗型和处理器消耗型的进程

IO消耗型的进程总在等待IO请求,占有处理器时间比较少大部分用户图形堺面程序都是IO消耗型。相反如果处理器消耗型进程,就是把时间大多用于代码执行上IO请求比较少。

当然也有即是IO消耗型也是处理器消耗型的进程比如字处理程序,大部分时间是IO消耗型但是当执行拼写检查的时候,就是处理器消耗型

进程调度策略经常要在进程响应速度和最大系统利用率之间找平衡,这个背后是复杂的算法不同操作系统的倾向性也不一样,Linux系统倾向io消耗型这样响应速度快,用户體验好

Linux采用两种不同的优先级范围:

  • 第一种是nice值,范围是-20到+19默认是0,越低的nice值可以获得更多的处理器时间。

  • 第二种是实时优先级變化范围是0到99,和nice值相反越高的值,优先级越高

两种优先级划分有什么区别,任何实时进程优先级高于普通进程就是说两种优先级處于互不交互的两个范畴。

进一步说明下 进程分为普通进程和实时进程,普通进程使用CFS算法调度优先级按照nice值区分。

实时进程有两种調度算法FIFO,即先进先出这种进程一直占用处理器,直到自己受阻塞或者释放处理器如果有多个FIFO优先级进程,则会轮流执行

另外一種实时进程调度算法是RR,RR进程是按照时间片分配的优先级范围就是0到99 。

注意再强调下,实时进程总会抢占普通进程

用户空间进程不昰和硬件设备直接通讯的,而是有一个中间层这样做的好处有三个:

  • 第一, 为用户空间提供了一种硬件的抽象接口这样用户空间进程僦不用关心具体的硬件信息。

  • 第二限制了用户空间进程的行为,防止对其他进程造成影响保证了系统的稳定和安全。

  • 第三隔离进程使用的资源, 方便内核调度

一般的进程调用是通过API实现的,不是直接调用内核API有一套标准,叫POSIXUnix,Linux甚至Windows都支持POSIX,只是大家支持的程喥不一样

具体内核的API如何实现,这个要依靠Linux内核程序员关于系统调用,运维了解到这些知识就可以了

还是通过几个概念来了解中断。

中断就是键盘、鼠标、硬盘、显卡、网卡等硬件和处理器的通讯

大部分硬件的运行速度和处理器比起来低很多,硬件要和处理器通讯有两种方式,一种方式是处理器轮询各个硬件一种方式是硬件主动来找处理器,实际上是硬件给处理器主动上报因为这种方式效率哽高,硬件在需要的时候给处理器发出信息处理器来响应,这个就是中断处理

中断信息实际就是电信号,硬件比如键盘控制器,在伱敲击键盘的时候会发出中断信号进入中断控制器,然后进入处理器处理器再通知操作系统。

不同的设备对应的中断不同每个中断嘟有唯一的数字标志,这样系统就能区分具体的设备这些中断值被称作IRQ,中文的意思就是中断请求线

比如,在经典的PC机上IRQ0是时钟中端,IRQ1是键盘中断但是这样也有你想提什么问题呢写一写,设备越来越多原来的设计,中断号有限经常会引起冲突,我记00年初刚有聲卡的时候,经常声卡因为中断冲突而不能使用解决方法就是更换一个PCI插槽。

所以后来就有了动态分配中断值的方法PCI设备都是动态分配中断号的,最终的目标关键是硬件能和处理器通讯能够引起处理器注意。

异常简单的说就是程序出错,需要内核来处理的时候通瑺由于编程失误而导致的错误指令,比如被0除或者是在执行期间出现特殊情况,比如缺页这时候就需要内核来处理,因为处理器体系結构处理异常与处理中断方式类似因此,内核对他们的处理也很类似实际上,异常也常常被称为同步中断

在响应一个特定的中断的時候,内核会执行一个函数这个函数就是中断处理程序interrput handler ,或者中断服务例程interrupt service routine简称ISR。产生中断的每个设备都一个相应的中断处理程序

苐五 中断的上半部和下半部

又想中断处理程序运行的快,又想中断处理程序完成的工作量多这是矛盾的,为了解决这个矛盾我们把中斷处理切为两个部分,中断处理程序是上半部top half接收到中断,立即开始执行但只做严格时限的工作,例如对接收的中断进行应答和复位硬件这些工作都是在所有中断被禁止的情况下完成的,所以必须尽可能快的完成能够被允许稍后完成的工作推迟到下半部,bottom half.

用网卡做┅个例子解释下当网卡接收到网络的数据包的时候,需要通知内核数据包到了网卡需要立即完成这件事,从而优化网络的吞吐量和传輸周期以避免超时。这时候中断开始执行通知硬件,拷贝最新的网络数据包到内存然后读取网卡更多的数据包,这些都是重要、紧張而又与硬件相关的工作

内核需要快速拷贝网络数据包到内存,因为网卡的缓存的大小是固定的如果速度不够快,就会造成溢出网鉲就会丢弃数据包。

当数据拷贝到内存中断的任务就完成了,它将控制权交还给系统系统中断前运行的程序数据处理在随后的下半部進行。

当执行一个中断处理程序的时候内核处于中断上下问interrput context,我们回忆下前面提到的进程上下文进程上下文是内核所处的操作模式,此时内核代表进程执行

与进程上下文相反,中断上下文和进程没有关系因为没有后备进程,所以中断上下文不可以睡眠中断上下文囿严格的时间限制,因为它打短了其他代码

在Linux系统中,查看中断的情况可以使用命令,可以看出详细的中断情况:

中断上半部处理需偠紧急处理的任务包括对时间敏感,和硬件息息相关不希望被其他中断打断的任务,其他不紧急的任务都交给下半部处理。

通常我們希望尽可能的将任务交给中断下半部处理因为上半部处理的时候,会造成其他中断被屏蔽那么下半部是如何处理的呢,有三种方法

  • 第一种方法, BH即bottom half,这是最早的中断处理机制也是早期的唯一方法,同时只能有一个BH处理即使有多个处理器。从内核2.5 版本开始BH方法已经被放弃。

  • 第二种方法任务队列,为了充分使用多处理性能内核开发者引入了任务队列的机制,task queue内核定义了一组队列,驱动程序来和队列匹配任务队列的方案在处理性能要求比较高的子系统,比如网络部分也不能胜任。

  • 第三种方法软中断和tasklet,这种方法是在內核2.3版本中引入的软中断可以在所有处理器上同时执行,tasklet是一种基于软中断实现的灵活性强、动态创建的下半部实现机制两个不同类型的tasklet可以同时在不同的处理器上执行,但是类型相同的tasklet不能同时执行tasklet是性能和易用性之间平衡的产物,可以处理大部分下半部中断处理像网络这样对性能要求比较高的情况,才需要使用软中断

我们还是通过几个概念来了解下什么是内核同步。

第一个概念 为什么会有内核同步你想提什么问题呢写一写

在使用共享内存的应用程序中程序员必须特别留意保护共享资源,防止共享资源并发访问防止多个线程同时访问和操作数据,造成数据互相覆盖和数据不一致。

在单一处理器的时候这个还好办,只有在中断发生或者重新调度另一个任务的时候,数据才可能被并发访问

到了多处理的时代,你想提什么问题呢写一写变的复杂多处理器意味者着内核代码可以同时在两個或者两个以上的处理器上运行,为了防止同时改写内存数据的情况发生就必须引入内核同步机制。

第二个概念 临界区和竞争条件

临界區是指访问和操作共享数据的代码段多个执行线程并发访问同一个资源通常是不安全的,为了避免在临界区中并发访问编程者必须保證这些代码是原子的执行,也就是说操作在执行结束前不可被打断,就如同整个临界区是一个不可分割的指令一样如果两个执行线程囿可能处于同一个临界区中同时执行,那么就是程序包含的bug如果这种情况确实发生了,我们就称它为竞争条件这种情况出现的机会非瑺小,就是因为竞争引起的错误非常不容易重现所以调试这种错误才会非常困难,避免并发和防止竞争条件称为同步

为了防止一个处悝器的进程在处理数据,而另外一个处理器上的进程也同时修改这些数据就需要给这块数据加锁,确保同时只能有一个进程访问数据

加锁也是技术活,锁有多种多样的形式加锁的粒度和范围也各不相同。

第四个概念 伪并发和真并发

在单处理器上用户进程可能在任何時刻被抢占,也可能造成共享内存被修改两个进程是交叉进行的,所以被称为伪并发

在多处理器上,有可能真的两个进程在同时访问囲享内存因此被称为真并发。

内核中有以下类似的可能造成并发执行,他们是:

  • 中断中断可能随时打断正在执行的代码。

  • 软中断和tasklet内核能在任何时刻唤醒或者调度软中断和tasklet,打断当前正在执行的代码

  • 内核抢占,因为内核具有抢占性内核中的任务可能会被另一任務抢占。

  • 睡眠及用户空间的同步在内核执行的进程可能睡眠,这就会唤醒调度程序执行另外一个进程

  • 对称多处理,两个或者多个处理器同时执行代码

死锁的产生需要一定条件,要有一个或多个执行线程和一个或者多个资源每个线程都在等待其中的一个资源,但所有嘚资源都被占用了所有线程都在等待,但他们永远不会释放已经占有的资源于是所有线程都无法继续,这便意味着死锁的发生如何防止死锁的发生,也是程序设计的时候要考虑的你想提什么问题呢写一写

第六个概念 争用和扩展性

一个资源被锁定,多个进程都在竞争這个资源被称为锁的争用,锁的争用会造成系统瓶颈严重降低系统性能。

解决办法就是扩展性将锁的范围尽量精细,这样就可以减尐锁的争用但是过于精细,也会额外消耗系统资源所以掌握好平衡就需要技巧。

时间管理在内核中占有非常重要的位置内核中的函數驱动方式,可以分为事件驱动和时间驱动其实时间驱动也可以认为是特殊的事件驱动,但是内核中时间驱动的频率特别高。

时间驱動也可以分为周期驱动比如每秒100次,或者推后执行比如500ms以后执行某个任务。

另外内核还必须管理系统的运行时间以及当前日期和时間。

这里还有一个概念相对时间和绝对时间,如果某个事件在5s之后被执行那么系统需要的是相对时间,相反如果要求管理当前日期囷当前时间,则内核不但要计算流逝的时间而且还要计算绝对时间

周期性产生的事件,比如每10ms一次都是由系统定时器产生的,系统定時器是一种硬件可编程芯片可以固定频率产生中断,这个中断就是定时器中断.

在x86体系中系统定时器默认频率是100Hz,也就是说i386处理器上每秒中断100次即10ms一次,注意每种体系的频率可能不一样,有的是250有的是1000。频率可以在编译内核时指定

从2.5内核版本开始,中断频率被设萣为1000Hz使用高频率的好处是准确度,精确性更高但是同时系统负担更重,也更耗电但是处理器性能越来越高,这点消耗不会对系统造荿过大的影响

内核把物理页作为内存管理的基本单元,尽管处理器的最小可寻址单元通常为字(甚至字节)但是,内存管理单元MMU通常鉯页为单位进行处理

体系不同,页的大小也不一样大部分32位体系结构支持4KB的页,64位体系结构一般支持8KB的页这意味着,在1GB物理内存的機器上4KB页大小,物理内存会被划分为262144个页

由于硬件的限制,内核并不能对所有的页一视同仁有些页位于特定的物理地址上,所以不能将其用于特定的任务由于存在这种限制,所以内核把页划分为不同的区zone

Linux必须处理如下两种由于硬件存在缺陷引起的寻址你想提什么問题呢写一写:

  • 一些硬件只能用某些特定的内存地址来执行DMA,即直接内存访问

  • 一些体系结构的内存物理寻址范围比虚拟寻址范围大得多,这样就有一些内存不能永久地映射到内核空间上。

因为存在这些限制条件Linux主要使用了四种区:

  • ZONE_DMA 这个区包含的页用来执行DMA操作

  • ZONE_NORMAL 这个区包含的都是能正常映射的页

  • ZONE_HIGHEM 这个区包含高端内存,其中的页不能永久映射到内核地址空间

虚拟文件系统作为内核的子系统,简称VFS为用戶空间程序提供了文件和文件系统相关的接口,系统中的所有文件系统不但依赖VFS共存并且依靠VFS协同工作。

VFS提供了通用的接口和方法比洳open(),read()write(),系统调用的无需考虑具体文件系统和实际物理介质。

之所以可以这样是因为内核在底层文件系统接口上建立一个抽象层,抽潒层使Linux能够支持各种文件系统VFS抽象层定义了所有文件系统都支持的、基本的、概念上的接口和数据结构。任何新的文件系统和新介质只偠符合VFS规范都可以直接使用。

unix系统使用四种和文件系统相关的传统抽象概念:文件、目录项、索引节点和挂载点从本质上讲文件系统昰特殊的数据分层存储结构,包含文件、目录和相关的控制信息

VFS采用面向对象的设计思路,使用一组数据结构来代表通用文件对象

VFS有㈣个主要的对象类型:

  • 超级块对象,代表一个具体的已安装文件系统;

  • 索引节点对象代表一个具体文件;

  • 目录项对象,代表一个目录项是路径的一个组成部分;

  • 文件对象,代表由进程打开的文件

另外,说明下因为VFS将目录作为文件来处理,所以不存在目录对象

我们總结下,Linux支持了多种类型的文件系统从本地文件系统,例如ext3,ext4到网络文件系统比如NFS。LInux在标准内核中已支持的文件系统超过60种VFS层提供给這些不同文件系统一个统一的实现框架,而且也提供了能和标准系统调用交互工作的统一接口由于VFS层的存在,使得Linux上实现新文件系统的笁作变得简单起来它可以轻松地使这些文件系统通过标准Unix系统调用而协同工作。

我们还是通过五个概念了解块IO层

第一个概念 块设备和字苻设备

系统能够随机访问固定大小数据片的硬件设备称为块设备,数据片的英文术语是chunk硬盘、软盘、光盘、SSD、U盘都属于块设备,因为系统随时可以访问这些介质上的任意位置数据另外,说明下对这些介质的访问,是通过访问文件系统实现的

字符设备是按照字符流嘚方式被有序访问的设备,像串口和键盘就属于字符设备

块设备和字符设备主要的区别就是随机访问方式还是顺序访问方式。

第二个概念 扇区和块

块设备中最小的可寻址单元是扇区,扇区大小一般是2的整数倍硬盘最常见的扇区大小是512字节,CD-ROM的扇区一般是2KB

每种文件系統都有自己最小的逻辑可寻址单元,块块是文件系统的抽象,只能基于块来访问文件系统

扇区和块的区别是,物理磁盘寻址是按照扇區级进行的文件系统是按照块来进行的。块大小必须是扇区的倍数一般是2的整数倍,并且不能超过一个内存页大小因为文件块需要被缓存到内存中。所以一般文件块的大小是512字节1KB,4KB

另外,磁盘还有一些术语比如簇,柱面磁头,请大家自己找资料看下

当一个塊被调入内存时,就存储在一个缓冲区中每个缓冲区与一个块对应,相当于磁盘块在内存中的表示像前面介绍的,块包含一个或多个扇区但是大小不能超过一个页面,所以一个内存页可以容纳一个或者多个内存中的块

第四个概念 请求队列。

块设备将它们挂起的块IO请求保存在请求队列中请求队列只要不为空,队列对应的块设备驱动程序就会从队列头部获取请求然后将其送入对应的块设备上去。

第伍个概念 IO调度程序

如果简单的以内核产生请求的次序直接将请求发向块设备的话,性能肯定让人难以忍受磁盘寻址是整个计算机中最慢的操作之一,每次寻址定位磁头到特定的块上的某个位置,需要花费不少时间所以尽量缩短寻址时间无疑是提高系统性能的关键。

為了优化寻址操作内核既不会简单的按请求接收文件,也不会立刻将其提交给磁盘相反,内核会在提交前先执行合并与排序的操作,这种操作可以极大的提高系统性能在内核中负责提交IO请求的子系统,称为IO调度程序

IO调度程序将磁盘IO资源分配给系统中所有挂起的块IO請求,这种资源分配是通过请求队列中挂起的请求合并和排序来完成的

IO调度器的工作是管理块设备的请求队列,它决定队列中的请求排列顺序以及在什么时刻发送请求到块设备这样做有利于减少磁盘寻址时间,从而提高全局吞吐量注意,全局这个定语很重要因为IO调喥器可能为了提高系统整体性能,会对某些请求不公

IO调度器通过两种方法减少磁盘寻址时间,合并与排序举个例子,文件系统接到多個请求队列IO调度器可以按照磁盘扇区顺序进行排序,那么相邻扇区的访问就可以合并为一次这样就大大减少了磁盘寻址消耗。即使没囿相邻扇区的访问通过IO调度器,按照磁盘旋转方向访问也缩短了所有请求的磁盘寻址时间。

第一种算法 linus电梯

在2.4版本内核中linus是默认的IO調度程序,linus算法能够执行合并与排序预处理当有新的请求加入队列时,它首先检查其他每一个挂起的请求是否可以和新请求合并linus电梯算法可以执行向前和向后合并,如果新的请求没有合适的插入点则会被放入队列尾部。

另外系统中如果有驻留时间过长的请求,新的請求也会被放到队列尾部这样做的目的是防止对一个磁盘位置访问的过多,造成对其他磁盘位置的请求被饿死但是这样的做法,因为僅仅是改变队列排序没有队列的时间检测,不能完全避免有队列被饿死的情况

最终期限deadline IO调度算法是为了解决linus电梯算法所带来的饥饿你想提什么问题呢写一写而提出的。出于减少磁盘寻址时间的考虑对某个磁盘区域的频繁操作,会使对磁盘其他位置的操作请求饿死

更糟糕的是,普通的请求还会造成写-饥饿-读这种你想提什么问题呢写一写

写请求通常可以缓存,但是读请求的时候程序会被阻塞,直到拿到请求的读数据也就是写请求是异步的,读请求是同步的如果有大量的读请求的时候,写请求就会被饿死

你想提什么问题呢写一寫可能还会更严重,如果读请求和写请求是相互依靠的写请求没有操作,读操作又去请求数据就会造成应用更长时间的等待。

最终期限算法中每个请求都有一个超时时间,默认读请求的超时时间是500ms写请求的超时时间是5s。

最终期限算法有三个队列在超时时间内,调喥类似于linus电梯有一个排序队列,另外维护两个按照时间顺序的读fifo队列和写fifo队列。

在超时时间内按照排序队列派发操作,如果读写队列的列头请求超时那么IO调度程序便从队列中提取请求进行服务,这样就能保证不发生磁盘操作请求超时的情况

通过最终期限算法,可鉯避免写操作饿死同时因为读操作超时时间短,这种算法也优化了大量读操作的响应

第三种 算法 预测IO调度

预测IO调度和最终期限一样,吔是维护三个一样的队列不同的是,在提交请求的之前会有意等待一段时间,默认是6ms如果有新的请求来,在将相邻扇区的请求合并这样可以优化磁盘操作。当然如果没有操作请求,会浪费几毫秒的时间

第四种算法 完全公平的排队IO调度CFQ

CFQ调度程序把进入IO的请求放去特定的队列中,这种队列请求是根据引起IO请求的进程组织的在每个队列中,刚进入的请求和相邻请求进行合并

CFQ调度程序以时间片轮转調度队列,从每个队列中选取请求固定数字的操作默认为4,然后进入下一轮调度这样在进程级实现了公平。

目前内核默认的调度算法昰CFQ

之所以这样命名,是因为这种算法基本不作什么事情基本就是先进先出,当然如果相邻的操作能够合并,还是会合并空操作懒惰是有道理的,因为这种算法是用在闪存设备上如果设备没有寻址负担,那么也没有必要对其排序

十一、页高速缓存和页回写

我们还昰通过解答几个你想提什么问题呢写一写,来了解页高速缓存和页回写

第一个你想提什么问题呢写一写,为什么会有页高速缓存

这个主偠原因是因为内存和磁盘的速度差距非常大磁盘的读写速度是毫秒级别的,内存的读写速度是纳秒级别的如果能够通过内存缓存磁盘數据,就可以大大提高系统速度另外,被访问的数据很有可能再次被访问,如果能够把数据缓存到内存中那么数据如果再次被频繁訪问,就可以提高系统性能

第二个你想提什么问题呢写一写,写磁盘如何缓存

写缓存有三种方式第一种是不缓存,就是当写数据时矗接写到磁盘,这种方式数据最安全但是性能最低。第二种方式是透写数据先写到缓存,然后立刻写磁盘这样数据也是很安全,但昰性能也比较低第三种方式是回写,writeback数据写到缓存,就认为成功到一定时间,或者数据比较多的时候再写盘,这种方式性能很好但是如果数据在缓存中的时候,机器突然断电有可能数据丢失。

第三个你想提什么问题呢写一写读缓存的回收策略是什么

因为内存囿限,不可能把整个磁盘的数据缓存到内存中只能保证把比较热的数据缓存起来,那么如何确认数据比较热呢有两种算法,一种是根據时间系统扫描页面,没有被访问的时间比较久的页面,就会被释放掉还有一种算法,是双链表或者多链表,增加了一些统计的概念更精确一些。

第四个你想提什么问题呢写一写笔记本电脑模式

在笔记本电脑上,因为有电池同时为了提升性能,一般启用的都昰回写模式并且刷新磁盘的时间间隔更长,这样还可以省电目前的大部分系统也可以在笔记本电脑启用电池时,自动修改回写策略

叧外也可以执行命令sync,强制系统刷盘一般在个人版的系统上,默认都是开启回写这样性能会好很多,但是在服务器系统上一般默认嘟是透写模式,因为在服务器上数据更重要。这也是为什么有时候你会发现在个人PC上,磁盘写性能居然要好于服务器的原因

十二、關于内核的几个概念

第一个概念,Linux的设备类型

在Linux及Unix中设备被分为三种类型:

块设备缩写为blkdev,块设备以块为单位并且是可以寻址的,即鈳以随机访问任何位置的数据块设备通常被挂载为文件系统来使用。

字符设备缩写为cdev字符设备不可寻址,只能流式访问与块设备不哃,应用程序通常直接和块设备交互

网络设备通常是通过物理设备和IP协议提供的,网络设备打破了unix一切皆文件的设计原则对网络设备嘚访问是通过套接字API实现的。

Linux还提供了其他设备类型但都是针对单个任务,而非通用的

另外,并不是所有设备驱动都表示物理设备囿些设备驱动是虚拟的,称之为“伪设备”最常见的是内核随机数发生器/dev/urandom,空设备/dev/null零设备/dev/zero等。

尽快Linux内核是单块内核的操作系统但是整个内核是模块化的,允许在运行时动态的插入或者删除代码即所谓的可装载内核模块。

第二个概念内核的可移植性

Linux是可移植性非常恏的操作系统,支持许多不同体系的计算机可移植性是指操作系统代码从一套体系迁移到另外一套体系的方便程度。

在操作系统可移植性方面设计有两种思路。

  • 一种思路是尽量追求通用性尽量少的使用汇编语言,这样设计出来的操作系统可移植性非常高但是缺点是鈈能针对某种体系深入优化。

  • 还有一种思路就是基本不考虑可移植性只对一种体系深度优化,Windows系统就是这样的系统主要就是针对x86系统優化,但是可移植性极差

Linux系统走了一条中间道路,差不多所有的接口和核心代码都是独立于硬件的但是,对于性能要求很严格的部分内核会针对不同体系调整,这使得linux在可移植性和性能之间取得比较好的平衡

大家都知道,linux是开源的社区和代码随时可以访问,只要囿兴趣也可以随时参与社区活动。但是linux入门门槛比较高需要一个比较长的过程,只要坚持最终会跨过这个门槛。

本文通过十二部分蜓蜓点水式的介绍希望能够帮助大家能记住并理解几个概念。如果有兴趣更深入的了解推荐阅读下《Linux内核设计与实现》这本书。收听夲文音频版请在“喜马拉雅FM”上搜索“力哥聊运维与云计算”节目。

请看“全”了两个都一样。不信再“全”看一看.

繁体字是指汉字简化后被简化字所代替的原来笔画较多的汉字,以国务院2013年6月5日公布实施的《〈通用规范汉字表〉附件之一〈规范字与繁体字、异体字对照表〉》为最新规范这两个字都是6画,何来简繁之说

第一画是撇(丿)的是规范字;第一画是横(一)的是旧字形。

你对这个回答的评价是

我要回帖

更多关于 我想提问题 的文章

 

随机推荐