Linux核心技术学习笔记

为性能测试有选择学习

性能测试在分析问题时时常会对从操作系统的层级去分析问题,因此我们在对被测的系统有足够了解的基础上还需要对操作系统以及一些硬件原理有充分的认识,这个笔记是针对性能测试需要了解的系统级东西做摘抄,学习资料是深入理解Linux内核第三版。
其实在书中有些知识是过时的,但是这本书更像是幼儿园的学前教材,能帮我们打开通往计算机世界的大门,所以记这个笔记的目的并不是单纯的学书上的知识,而是做一个路标。

内存寻址

这章讲述cpu和Linux系统对内存得使用,需要记住得概念主要有逻辑地址,线性地址和物理地址,GDT(全局描述符标)和LDT(局部描述符表)。cpu在需要加载数据时先拿着地址在寄存器里找,如果没有去高速缓存里找,找不到再去主存,主存里没有会产生缺页异常。
缺页异常中的异常先暂且放下,这是中断和异常章节的内容。
缺页两个字需要单独理解,首先页是内存管理的基本单元,Linux将4B内存看作一个页,这个页被加载到主存后存放在主存的页框中;缺的意思是cpu拿着地址来找这个页的时候发现这个页不在主存上。

进程

1、进程是程序运行时的一个实例,是充分描述程序已经执行到何种程度的数据结构的汇集。
2、父子进程共享程序代码页,但是有各自的数据拷贝(暨堆栈)。
3、进程状态,这个挺重要的:TASK_RUNNING®,TASKINTERRUPTIBLE(S),TASK_UNINTERRUPTIBLE(D),TASK_STOP(T),TASK_TRACE(T),TASK_ZOMBIE(Z),TASK_DEAD(X)。括号里是监控时top的state字段显示字母,括号外是Linux内核定义的进程状态。
4、Linux内核把进程的进程描述符和内核态堆栈存放再两个连续的页框中,线程描述符(threadinfo)紧挨着进程描述符存放。
5、等待队列和运行队列,等待队列就是等待进程的队列,运行队列是运行进程的队列。
6、进程切换、上下文切换、任务切换都是一个东西。
7、进程欲恢复执行前须装入寄存器的一组数据被称为硬件上下文,硬件上下文是进程可执行上下文的一个子集,可执行上下文包含上下文的所有信息。Linux中硬件上下文一部分存在TSS段,剩余部分存在内核态堆栈中。
8、每次上下文切换时,被替换进程的硬件上下文被存放在进程描述符里。
9、上下文切换的本质是两步,一是切换全局目录,以安装一个新的地址空间。二是切换内核态堆栈和硬件上下文,因为硬件上下文提供内核执行新线程需要的所有信息,包括cpu寄存器。

中断和异常

1、中断通常被定义为一个事件,该事件改变处理器执行的指令顺序,该事件改变处理器执行的指令顺序,这样的事件与cpu芯片内外部硬件电路产生的电信号相对应。
2、中断分为同步中断和异步中断。同步中断是指当指令执行时,由cpu控制单元产生的,之所以时同步,是因为只有在一条指令终止执行后cpu才会发出中断;异步中断是由其他硬件设备,依照cpu时钟信号随机生成的。
3、同步中断我们称为异常,异步中断我们称为中断。
4、中断是由间隔定时器和io设备产生的,异常是由程序错误产生的(如缺页异常)。
5、中断信号提供一种特殊的方式,使处理器转而去运行正常控制流之外的代码。
6、当一个中断信号到达时,cpu必须停止它正在做的事情,并切换到一个新的活动,为了做到这一点,就需要在内核态堆栈保存程序计数器的当前值,并把与中断类型相关的一个地址放进程序计数器。
7、中断处理与进程上下文切换有明显的差异,由中断或异常处理程序执行的代码不是一个进程,更确切的说,它是一个内核的控制路径,代表中断发生时,正在运行的进程执行,作为一个内核控制路径,中断处理程序比一个进程要轻(中断上下文很少或终止中断处理需要的时间很少)。
8、中断与中断是嵌套执行的。

内核同步

1、你可以把内核堪称是不断对请求响应的服务器,这些请求可能来自cpu上执行的进程,也可能来自发出中断请求的外部设备。我们用这个类比来强调内核的各个部分并不是严格按照顺序依次执行的,而是采用交错执行的方式。因此,这些请求可能引起竞争条件,而我们必须采用适当的同步机制对这种情况进行控制(这段话很重要他为我们揭示了软件系统,不仅包括Linux内核在内的所有操作系统都有的一套逻辑,暨响应与同步,性能测试很多时候都是在他们之间找平衡。)。
2、内核如何为不同的请求提供服务。我们规定两种请求,老板请求和客户请求,内核是店员。老板请求相当于中断,而顾客请求相当于用户态进程发出的系统调用或异常。内核服务规则:一、老板提出请求,如果店员正空闲,则店员开始为老板服务。二、如果老板提出请求时店员正在为客户服务,那么店员停止为客户服务,开始为老板服务。三、如果一个老板提出请求时,店员正在为另一个老板服务,那么店员应该停止为第一个老板服务,而开始为第二个老板服务,服务完毕后再为第一个老板服务。四、一个老板可能命令店员停止为顾客提供服务。店员再完成对老板最近的请求后,可能暂时不会理会原来的阿古河而去为新选中的顾客服务。
3、在本章的其余部分,我们把系统调用和通常的异常都笼统的表示为异常。而从2中的第四条规则,引出下面要介绍的概念,叫内核抢占。
4、我们无法给内核抢占下准确的定义,因为应用情况是很复杂的,但是,简单的说就是,进程在内核态运行时,如果允许发生内核切换(暨被替换的进程时正在执行内核函数的进程),则这个内核就是抢占式的,至于抢占的条件我们不研究。

进程调度

写在前面的话:这章内容是非常重要的,它是性能测试需要理解的最高级理论,特别是web服务器等cpu密集型应用了解自己的线程在什么时候被执行是非常有必要的,但是同时这也是一个非常没有什么用的理论,它不能准确的判断出一个进程在什么时间会运行,但这是在微观上的,当我们把时间拉到秒级,也就是我们通常所观测的时间单位,这种理论加实践组合成的工具会在分析问题时成为最重要的武器。
一、调度策略
1、Linux的调度基于分时技术,多个进程以时间多路复用方式运行,因为cpu的时间被分成片,给每个可运行的进程分配一个片。如果当前运行进程的时间片或时限到期,该进程还没有运行完毕,进程切换就可以发生,分时依赖于定时中断,因此对进程是透明的,不需要再程序中插入额外的代码来保证cpu分时。
2、再Linux中,进程的优先级是动态的,调度程序跟踪进程在做什么,并周期性的调整他们的优先级,在这种方式下,在较长时间间隔没有使用cpu的进程,通过动态的增加他们的优先级来提升他们,相应的,对于已经在cpu上运行了较长时间的进程,通过动态的减少他们的优先级来出发他们。
3、当谈及有关调度的问题时,传统上把进程分为io受限或cpu受限。
4、进程的另一种分类,交互式进程,这些进程常与客户进行交互,因此,要花很多的时间等待键盘和鼠标的操作,当接受了输入后,进程必须被很快的唤醒,典型的时间时50-100ms,这样的延迟变化也必须进行限制,否则用户会发现系统是不稳定的。批处理进程,这些进程是不必与用户交互的,因此经常在后台运行。实时进程,这些进程有很强的调度需要,这样的进程绝不会被低优先级的进程阻塞,他们应该有一个短的相应时间,更重要的是,响应时间的变化应该很小。
二、进程的抢占
1、Linux的进程是抢占式的,如果一个进程进入TASK_RUNNING装态,内核检查它的动态优先级是否大于当前正在运行的进程的优先级。如果是,current的执行被中断,并调用调度程序选择另一个进程运行(通常是刚刚变为可运行的进程)。当然,进程在它的时间片耗尽后也可以被抢占。
三、调度算法
每个Linux进程总是按照下面的调度类型被调度。
SCHED_FIFO
先进先出的实时进程。当调度程序把cpu分给进程的时候,它把该进程描述符保留在运行队列链表的当前位置。如果没有其他可运行的更高优先级的实时进程,进程就继续使用cpu,想用多久就用多久,即使还有其他具有相同优先级的实时进程处于可运行状态。
SCHED_RR
时间片轮转的实时进程。当调度程序把cpu分给进程的时候,它把该进程的描述符放在运行队列的末尾。这种策略保证对所有具有相同优先级的SCHED_RR进程公平的分配cpu时间。
SCHED_NORMAL
普通的分时进程。
调度算法根据进程类型还是有很大差别的。
1、普通进程的调度,每个普通进程都有自己的静态优先级。调度程序使用静态优先级来估价系统中这个进程与其他普通进程直之间的调度的程度。内核从100(最高优先级)到139(最低优先级)的数表示普通进程的静态优先级。
2、新进程总是继承父进程的优先级,不过通过把这些nice值传递给系统调用,可以改这个值。
3、基本时间片,静态优先级决定了进程的基本时间片,当静态优先级小于120的时候,基本时间片等于(140-静态优先级)*20,当静态优先级大于等于120时,基本时间片等于140-静态优先级)*5.
4、动态优先级和平均睡眠时间,普通进程除了静态优先级,还有动态优先级,其值范围也是100-139,动态优先级和静态优先级的换算关系:动态优先级=max(100,min(静态优先级-bonus+5,139)),bonus的范围是0-10,bonus小于5,降低优先级,bonus大于5,增大优先级。
5、bonus的值和进程的平均睡眠时间有关系,粗略的讲,平均睡眠时间是进程睡眠状态所消耗的平均纳秒数。注意,这里不是对过去睡眠时间的求平均操作,例如,可中断和不可中断睡眠计算的结果是不同的。
6、平均睡眠时间越大,bonus越大。
7、Linux判断进程是否是交互进程的公式。如果bonus-5>=静态优先级/4–28,则这个进程是交互式进程。只要静态优先级/4-28这个值(进程交互标志)大于6,则这个进程一定是交互进程,根据p264的平均睡眠时间表,只要缺省静态优先级(120)的进程平均睡眠时间大于700ms,就为交互进程。
8、即使具有较高静态优先级的普通进程获得了较大的cpu时间片,也不应该使静态优先级较低的进程无法运行。为了避免进程饥饿,当一个进程用完它的时间片时,它应该被还没有用完时间片的低优先级进程取代,为了实现这种机制,调度程序维护了连个不相交的可运行进程集合,暨活动进程(这些进程还没有用完他们的时间片,因此允许他们继续运行),过期进程(这些进程已经用完了他们的时间片,并禁止被运行,直到所有的活动进程都过期)。
9、不过,总有复杂一点的方案,因为调度程序试图提升交互进程的性能,用完其时间片的活动批处理进程总是变成过期进程,用完其时间片的交互进程仍然是活跃进程,调度程序重新填充其时间片并把它留在活动进程集合中。但是如果最老的过期进程已经等了很长时间了,或者过期进程比交互进程的静态优先级更高,则调度进程就把用完时间片的交互进程移到过期进程集合中,结果,活动进程集合最终会变为空,过期进程将有机会执行。
10、实时进程的调度(这节存疑,主要是书中没有说明进程在什么情况下会变成实时进程)。
三、调度程序使用的数据结构
1、runqueue:每个cpu都有自己的运行队列。runqueue数据结构中最重要的字段是与可运行进程的链表相关的字段。系统中的每个可运行进程属于且只属于一个运行队列。只要可运行进程保持在同一个运行队列中,它就只可能在拥有该运行队列的cpu上执行。但是正如我们将要看到的,可运行进程会从一个运行队列迁移到另一个队列。

结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值