logo资料库

linux操作系统复习.pdf

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
UNIX系统的特点: 1. 简洁:仅有几百个系统调用,其他操作系统往往几千个 2. 所有的东西都被当做文件对待,这种抽象可以将数据和对设备的操作通过一套相同 的系统调用接口来进行:open(),read(),write(),lseek(),close() 3. Unix内核和相关系统工具软件是由C语言编写===>在各种硬件系统架构中有很好 的移植能力 4. unix进程创建十分迅速,提供了一个十分独特的fork()系统调用 5. 提供了一套十分简单又十分稳定的进程间通信元语 6. 采用了策略与机制分离的理念,unix系统具备清晰的层次化结构 linux系统: 基础:内核、c库、工具集、如登录程序、shell等系统的基本工具 内核的功能:管理硬件设备、分配系统资源等 内核由以下几大部分组成: 名称 中断服务程序 调度程序 内存管理程序 系统服务程序 功能 负责响应中断 负责管理多个进程并分配处理器时间 负责管理进程地址空间 网络、进程间通信等 用户空间:普通应用程序所在的空间 内核空间:系统态和被保护起来的内存空间 内核空间由内核子系统、设备驱动程序和系统调用接口组成。 与内核通信: 应用程序与内核通信:应用程序通过系统调用陷入内核 硬件设备与内核通信:中断机制 处理器活动状态: state1 运行于用户空间,执行用户进程 state2 运行于内核空间,处于进程上下文,代表某个特定的进程执行 state3 运行于内核空间,处于中断上下文,与任何进程无关,处理某个特定的中断 linux内核:单内核,但是支持动态加载内核模块、支持抢占(微内核的优点)
linux内核与unix内核的比较: linux支持动态的加载内核模块,在需要时可以动态卸载和加载内核代码 linux支持对称多处理机制(SMP) linux内核可以抢占,允许任务优先级 linux内核不区分线程与其他一般进程 linux提供具有设备类的面向对象的设备模型、热插拔事件以及用户空间的设备文件系统 26. 1 修订版本号 稳定版本号(可选) linux内核版本:比如2.6.26.1 2. 主版本号 6. 从版本号: 偶数代表稳定版本,奇数代表开发版本 内核开发的特点: feature1 内核编程时不能访问C库与标准的头文件 feature2 内核编程必须使用GUN C feature3 内核编程无用户空间那样的内存保护机制 feature4 内核编程时很难执行浮点运算 feature5 内核给每个进程只有很小的内核堆栈 feature6 注意同步与并发 进程管理: 进程 线程 处于执行期的程序以及相关资源的总称,由唯一的进程标识符PID来标识 进程提供的虚拟机制 虚拟内存  and 虚拟处理器 进程描述符 包含一个具体进程的所有信息: 打开的文件、进程的地址空间、挂起的信号、进程的状态等 任务队列 一个双向循环链表,进程描述符存放在其中 进程的状态 进程上下文 运行;准备;等待---睡眠;停止; state域的5种取值: 运行;可中断;不可中断;被其他进程跟踪;停止; 一个程序调用了系统调用或者触发了某个异常,陷入内核空间,称内核代
表进程执行并处于进程上下文 解释: 一个进程在执行的时候,CPU的所有寄存器中的值、进程的状态以及堆栈 上的内容,当内核需要切换到另一个进程时,它需要保存当前进程的所有 状态,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复 切换时的状态,继续执行 推迟甚至免除copy的技术,资源的复制只在需要写入的时候才进行,之前 就只是以只读的方式共享 fork()函数通过拷贝当前进程创建一个子进程,然后exec()函数产生新的地 址空间,然后读取可执行文件并将其载入地址空间开始运行 fork()函数在调用clone系统调用时需要传递一些参数标志来指明需要共享 的资源 写时拷贝 进程创建的方法 线程创建的方法 进程调度: I/O消耗型进程 进程大部分时间用来提交I/O请求或等待I/O请求-------例如GUI--I/O密集型 处理器消耗型进程 进程把大部分时间用来执行代码 调度策略平衡 进程响应迅速与最大系统利用率之间寻求平衡 进程优先级 CFS调度算法 CFS使用RB-tree 两种优先级范围: nice值:-20--19,nice值越大优先级越低 实时优先级:0--99,值越大,优先级越高 允许每个进程运行一段时间、循环轮转、选择运行最少的进程作为下一个运行进 程,而不再采用给每个进程分配时间片的做法。 解释: CFS调度器的抢占时机取决于新的可运行程序消耗了多少处理器使用比,如果消 耗的使用比比当前进程小,则新进程立刻投入运行,抢占当前进程,否则推迟运 行。 CFS使用红黑树来组织可运行进程队列,利用红黑树这种自平衡二叉搜索树的性 质来迅速找到最小vruntime的进程 方式: 运行RB-tree中最左边叶子结点所代表的那个进程 系统调用: 系统调用的作用 1、为用户空间提供了一种硬件的抽象接口 系统调用号 系统调用的实现 调用系统调用 2、系统调用保证了系统的稳定和安全 系统调用号独一无二,已经分配,不能变更,即使系统调用被删除,系统调用号 也不允许被回收 1、编写系统调用函数 2、将其函数声明添加到系统调用头文件中 3、在系统调用表中加入其的系统调用号 4、将新建的系统调用编译进内核 1、编写调用的系统调用函数,添加上标准头文件、C库链接 2、编译运行调用函数 当 一 个 进 程 在 执 行 时 , C P U 的 所 有 寄 存 器 中 的 值 、 进 程 的 状 态 以 及 堆 栈 中 的 内 容 被 称 为 该 进 程 的 上 下 文
调用系统调用 2、编译运行调用函数 3、使用dmesg查看日志 内核数据结构: 链表 队列 映射 红黑树 如何选择合适 的数据结构 1、存放和操作可变数量元素(节点)的数据结构 2、无须连续内存区域,从链表中增加或删除节点只需要调整一下指向下一节点的指针 即可 3、节点由数据域和指针域组成 1、实现生产者和消费者模型的数据结构 2、数据元素先入先出,主要有2个操作:入队列和出队列 1、关联数组,一个由唯一键组成的集合,每个键必然关联一个特定的值 2、主要是映射一个唯一的标识数(UID)到一个指针 1、一种自平衡二叉搜索树 2、最深的叶子结点的深度不会大于最浅叶子结点深度的2倍 3、在插入和删除节点的时候永远维持半平衡树 链表:对数据集合的主要操作是遍历数据;存储较少数据项;与内核中其他使用链表 的代码交互时; 队列:符合生产者消费者模式;定长缓冲; 映射:映射一个UID到对象; 红黑树:存储大量数据,并且需要检索迅速 算法的复杂度 大O:上限 大Q:既是上限也是下限 中断和中断处理程序: 中断 设备向处理器发送异步的电信号,打断处理器的执行,进而打断内核的执行,从而与 系统通信 中断响应过程 设备产生中断,将中断发送给中断控制器,如果中断线是激活的,中断会被发送到处 理器,如果处理器未禁止该中断,处理器会中断内核,然后开始执行中断处理程序 中断上下文 硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件 的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理 中断会打断内核中进程的正常调度运行,所以要求中断服务程序尽可能的短小精悍既 由于我们既希望中断处理程序运行快,又希望中断处理程序完成的任务量多,出现了 上下半部机制。 上下半部的来 源 中断上半部 处理紧急功能,关中断执行 中断下半部 处理允许稍后完成的功能,开中断执行 中断注册过程 1、使用request_irq()函数注册中断处理程序,激活中断线 2、irq -分配中断号 3、handler-指向处理中断的实际中断处理程序 4、设置中断处理程序标志 下半部与退后执行的工作: 下半部的任务 执行与中断处理密切相关但中断处理程序本身不执行的工作 软中断 tasklet 一组静态定义的下半部接口,32个,可以在所有处理器上同时执行,两个类型一样的 软中断也行 允许响应中断,不能休眠 软中断之间不会相互抢占,只有中断处理程序会抢占软中断 基于软中断实现的灵活性强、动态创建的下半部实现机制
两个不同类型的tasklet可以在不同的处理器上执行,相同类型的tasklet不可以 由内核线程实现,一个用户创建内核线程的接口,通过它创建的进程负责执行由内核 其他部分排到队列里的任务 允许重新调度甚至睡眠 将工作推后交给内核线程去执行——整个过程是在进程上下文中执行 软中断:代码本身多线索化工作做得很好,完全使用单处理器变量 tasklet:不需要睡眠,代码对线索化工作考虑不充分 工作队列:易于使用;需要睡眠; 工作队列 下半部机制的 选择 3种下半部机制的比较: 下半部 软中断 tasklet 工作队列 内核同步: 临界资源的定 义 上下文 中断 中断 进程 顺序执行保障 没有 同类型不能同时执行 没有,和上下文一样被调度 一次仅允许一个进程使用的共享资源 临界区的定义 每个进程中访问和操作临界资源的那段代码 竞争条件 当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程进行的顺序 时,我们认为发生了竞争条件 避免并发和防止竞争条件 同步(加锁) 的意义 死锁的概念 一个或多个执行线程和一个或多个资源,每个线程都在等待其中的一个资源,但是所 有资源都已经被占用 内核同步的方法: 原子操作 自旋锁 保证指令以原子的方式执行,执行过程不被打断 原子整数操作  and  原子位操作 1、一个自旋锁只能被一个线程持有,如果有其他线程想要获得一个被持有的自旋 锁,那么该线程将会一直进行忙循环-旋转,等待锁重新可用 2、自旋:十分浪费处理器时间,所以自旋锁不应该被持有,一般自旋时间小于两次 上下文切换用时 3、自旋锁不可以递归 4、不对临界区进行区分 5、应用:加锁时间不长且代码不会睡眠 读写自旋锁 顺序锁 1、读者锁:一个或多个读任务可以并发持有读者锁 2、写者锁:只能被一个写任务持有,且不能有并发的读操作 3、对临界区进程读写区分 4、适用于:读或写/消费者与生产者类型;读进程多于写进程 对某一个共享数据读取的时候不加锁,写的时候加锁。同时为了保证读取的过程中因 为写进程修改了共享区的数据,导致读进程读取数据错误。在读取者和写入者之间引 入了一个整形变量sequence,读取者在读取之前读取sequence, 读取之后再次读取
此值,如果不相同,则说明本次读取操作过程中数据发生了更新,需要重新读取。而 对于写进程在写入数据的时候就需要更新sequence的值。 应用场景: 1、数据读取多,写入少 2、希望写进程优先于读进程,而且不允许读进程让写进程饥饿 3、数据结构简单 1、一种睡眠锁,一个任务试图获得一个不可用的信号量时,信号量会将其推进到一 个等待队列,然后让其睡眠 2、特点:适用于锁被长时间持有的情况;只能在进程上下文中获得信号量锁;占用 信号量的同时不能占用自旋锁 3、计数信号量(允许多个任务持有锁) and  二值信号量(仅允许一个任务持有锁, 类似自旋锁) 1、实现互斥的特定睡眠锁,是一种互斥信号 2、上锁者自己负责解锁 3、不允许递归上锁和解锁 4、进程持有一个mutex不允许退出 5、mutex不可以被copy、手动初始化或重复初始化 自旋锁:低开销加锁;短期锁定;中断上下文加锁; 互斥体:长期加锁;持有锁需要睡眠 信号量 互斥体mutex 自旋锁与互斥 体的区别与应 用
分享到:
收藏