《Linux内核设计与实现》读书笔记
《Linux内核设计与实现》读书笔记
第三章 进程管理 第四章 进程调度 第五章 系统调用 第六章 内核数据结构 第七章 中断和中断处理 第八章 下半部和推后执行的工作 第九章 内核同步介绍 第十章 内核同步方法 第十一章 定时器和时间管理 第十二章 内存管理 第十三章 虚拟文件系统 第十四章 块IO层 第十五章 进程地址空间 第十六章 页高速缓存和页回写 第十七章 设备与模块
第三章 进程管理
Linux中线程和进程并不特别区分,对Linux而言,线程只不过是一种特殊的进程罢了。 创建一个新进程,fork->exec。fork返回两次,一次在父进程返回,一次在子进程返回;exec创建新的地址空间,把新的程序载入。 存储进程的数据结构是双向循环链表。进程描述符task_struct在32位机器上,大约有1.7KB。 进程描述符中:PID唯一标识一个进程;state对应进程5种状态(运行、可中断、不可中断、被追踪、停止); 进程创建时,只有资源在需要被写入时才会发生拷贝,即写时拷贝 从Linux内核角度来说,没有线程的概念,因为线程仅仅被视为一个鱼其他进程共享某些资源的进程,每个进程(线程)有隶属于自己的task_struct。
第四章 进程调度
抢占:进程会被操作系统强制挂起。让步(yield):进程主动挂起 Linux采用两种不同的进程优先级表示:①:nice值,-20~+19,越低,优先级越高;②:实时优先级,0~99,任何实时进程的优先级都高于普通进程。 CFS(完全公平调度),在Linux中称为SCHED_NORMAL。他能确保给每个进程公平的处理器使用比,不完全公平,但是近乎完美的多任务。 静态优先级,nice值,权利在用户;动态优先级,权利在系统 O(n)调度器:链表;O(1)调度器:bitmap位运算 实时调度策略:SCHED_FIFO和SCHED_RR。 每个 CPU 都有自己的运行队列(Run Queue, rq),用于描述在此 CPU 上所运行的所有进程,其队列包含三个运行队列,Deadline 运行队列 dl_rq、实时任务运行队列 rt_rq 和 CFS 运行队列 cfs_rq,其中 cfs_rq 是用红黑树来描述的,按 vruntime 大小来排序的,最左侧的叶子节点,就是下次会被调度的任务。 nice值越高,权重越大,虚拟运行时间就会越小,下一次再红黑树中选任务的时候就会更大几率选中。
第五章 系统调用
每个系统调用都会对应一个系统调用号。系统调用会触发软中断,中断号为int &0x80。x86系统上,系统调用号是通过eax寄存器传递给内核的,系统调用的参数通过其他参数寄存器传递。
第六章 内核数据结构
使用链表存放数据的理想情况是,需要遍历所有数据或要动态加入和删除数据时。 映射在Linux中也是一种数据结构,就相当于是map,更确切地说是键值对。 二叉树,Linux中常用自平衡二叉树,即红黑树。
第七章 中断和中断处理
每个中断会对应一个中断号,对应一个中断处理程序(中断服务例程ISR) 异常,常常也称为同步中断。 上半部和下半部:有个矛盾的点,又想中断程序运行得快,又想中断程序完成更多的工作量。处于这点,专家们把中断处理程序分成上半部和下半部。上半部接收到中断,就立即开始执行,但只做有严格时限的工作,例如对接受的中断进行应答或者复位硬件,这些工作都是在所有中断都被静止的情况下完成的。其他能够推迟的工作,比如数据具体的处理方式可以延迟到下半部去处理。 中断处理程序无需重入,因为当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止在同一中断线上接收另一个新的中断。 有一点非常重要,请牢记:中断处理程序打断了其他代码。
第八章 下半部和推后执行的工作
任务划分的到上半部下半部的粒度(建议):①如果一个任务对时间非常敏感,将其放在上半部;②如果一个任务和硬件相关,将其放在上半部;③如果一个任务保证不被其他打断,放在上半部;④其他任务放在下半部 上半部简单快速,执行的时候禁止一些或者全部中断;下半部一般在中断返回的时候执行,执行期间可以相应中断。这种设计可系统处于中断屏蔽状态尽可能的短,以此来提高系统的响应能力。 下半部的实现方式:软中断、tasklet、工作队列。tasklet基于软中断实现,工作队列基于内核线程实现。软中断和tasklet的上下文是中断,工作队列的上下文是进程。工作队列中的人物允许休眠,换句话说他有自己的实体,即他牵扯到进程上下文切换,因此开销大。
第九章 内核同步介绍
避免并发和防止竞争条件称为同步。 可能造成并发的原因:中断、软中断和tasklet、内核抢占、睡眠及用户空间同步、对称多处理 异步:异步双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接收的信息【百度百科】 加锁的情况:如果其他执行线程可以访问这些数据、如果其他什么东西能看到它,那么,就需要锁住它!几乎所有的内核全局变量和共享数据都需要某种形式的同步方法。 争用:锁被占有时,其他线程视图获取锁的情况就叫争用。
第十章 内核同步方法
原子操作:保证操作以原子的方式执行----执行过程不被打断。Linux内核提供了对整数、位的原子操作。 整数操作,atomic_t、atomic64_t,低八位是锁 自旋锁:在短期内进行轻量级加锁,持有自旋锁的时间最好是小于完成两次上下文切换的耗时。自旋锁不可递归。在中断处理程序中使用自旋锁时,一定要在获取锁之前,首先禁用本地中断,否则,中断处理程序就会打断正在持有锁的内核代码,有可能会试图去争用这个已经被持有的自旋锁。 锁,锁的是数据,而不是代码。 再对于持有锁时间较长的场景,适合使用信号量。在持有信号量锁时,允许任务进入睡眠状态(自旋锁不允许这样的事情发生)。互斥量就是使用计数为1的信号量,但是他提供更为简单易用的接口。 完成变量:一个任务需要发出信号通知另一个任务发生了某个特定的事件时使用。 rmb()、wmb()是阻止跨越屏障的载入/存储动作发生重排序的函数。
第十一章 定时器和时间管理
提高节拍率带来的好处:更高的时钟中断解析度可以提高驱动时间的解析度、提高了时间驱动事件的准确度。 高HZ的劣势:节拍率越高,意味着时钟中断频率越高,中断处理程序占用的处理器的时间越多,耗电多。 jiffies是一个全局变量,用来记录自系统启动以来产生的节拍的总数,系统启动时,初始化为0.
第十二章 内存管理
kmalloc函数确保页在物理地址上是连续的 vmalloc函数只确保也在虚拟地址空间内连续 栈溢出可能会危及thread_info的数据 内核和用户空间不同,他不具备简单便捷的内存分配方式。因为,内核一般不能睡眠,且内核处理内存分配错误对内核来说不是容易的事。
第十三章 虚拟文件系统
VFS把各种不同的文件系统抽象后采用统一的方式进行操作。抽象层使得Linux能够支持各种文件系统,即便是他们在功能和行为上存在很大差别。VFS抽象层之所以能够衔接各种各样的文件系统,是因为他们定义了所有文件系统都支持的、基本的、概念上的接口和数据结构。 在Windows中,将文件的命名空间分类为驱动字母,例如C:,这种命名空间划分为设备和分区的做法没相当于把硬件细节“泄露”给文件系统抽象层。 文件相关信息有时被称为文件的元数据,该结构被称为索引节点,inode。文件系统的信息存储在超级快中。 Linux 文件系统会为每个文件分配两个数据结构:索引节点(index node)和目录项(directory entry),它们主要用来记录文件的元信息和目录层次结构。索引节点 ,也就是 inode,用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同样都会被存储在硬盘中,所以索引节点同样占用磁盘空间。目录项 ,也就是 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。目录也是文件,也是用索引节点唯一标识,和普通文件不同的是,普通文件在磁盘里面保存的是文件数据,而目录文件在磁盘里面保存子目录或文件。 文件系统的基本操作单位是数据块。 硬链接是多个目录项中的「索引节点」指向一个文件,也就是指向同一个 inode,但是 inode 是不可能跨越文件系统的,每个文件系统都有各自的 inode 数据结构和列表,所以硬链接是不可用于跨文件系统的,由于多个目录项都是指向一个 inode,那么只有删除文件的所有硬链接以及源文件时,系统才会彻底删除该文件;软链接相当于重新创建一个文件,这个文件有独立的 inode,但是这个文件的内容是另外一个文件的路径,所以访问软链接的时候,实际上相当于访问到了另外一个文件,所以软链接是可以跨文件系统的,甚至目标文件被删除了,链接文件还是在的,只不过指向的文件找不到了而已。
第十四章 块IO层
系统中能够随机(不需要按顺序)访问固定大小数据片的硬件设备称作块设备,这些固定大小的数据片就称为块。如果一个硬件设备是以字符流的方式被访问的话,那就应该将它归于字符设备;反过来,如果一个设备是随机(无序)访问的,那么他就属于块设备。 扇区是设备的最小寻址单元;块时文件系统的最小寻址单元。 当一个块呗调入内存时,他要存储在一个缓冲区中。每个缓冲区对应一个块,它相当于是磁盘块在内存中的表示。每个缓冲区都有一个缓冲区头,存储相关块的控制信息。 缓冲区头的弊端:①缓冲区头是一个很大且不容易控制的数据结构体;②他仅能描述单个缓冲区,造成不必要的空间浪费。 IO调度:FIFO、最短寻道、Scan、C-Scan
第十五章 进程地址空间
内存描述符中:页全局目录、代码段开始结束地址、数据、堆、进程栈、命令行参数、环境变量开始结束地址
第十六章 页高速缓存和页回写
写缓存有三种策略:①不缓存:高速缓存不缓存任何写操作,直接写回磁盘,且不缓存;②写透缓存:更新缓存、更新磁盘;③回写:只写入缓存,并标记为脏,由另一进程周期性地写回磁盘
第十七章 设备与模块
设备类型:块设备、字符设备、网络设备 一些”伪设备“:内核随机数发生器/dev/random、空设备/dev/null、零设备/dev/zero、满设备/dev/full
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/24714.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!