| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> ubuntu-6-操作系统详解 -> 正文阅读 |
|
[系统运维]ubuntu-6-操作系统详解 |
参考操作系统详解 1 概述1.1 基本特征一、并发 并发是指宏观上在一段时间内能同时运行多个程序,而并行则指同一时刻能运行多个指令。 并行需要硬件支持,如多流水线、多核处理器或者分布式计算系统。 操作系统通过引入进程和线程,使得程序能够并发运行。 二、共享 有两种共享方式:互斥共享和同时共享。 互斥共享的资源称为临界资源,例如打印机等,在同一时刻只允许一个进程访问,需要用同步机制来实现互斥访问。 三、虚拟 虚拟技术把一个物理实体转换为多个逻辑实体。 主要有两种虚拟技术:时(时间)分复用技术和空(空间)分复用技术。 多个进程能在同一个处理器上并发执行使用了时分复用技术,让每个进程轮流占用处理器,每次只执行一小个时间片并快速切换。 虚拟内存使用了空分复用技术,它将物理内存抽象为地址空间,每个进程都有各自的地址空间。地址空间的页被映射到物理内存,地址空间的页并不需要全部在物理内存中,当使用到一个没有在物理内存的页时,执行页面置换算法,将该页置换到内存中。 四、异步 1.2 基本功能一、进程管理 进程控制、进程同步、进程通信、死锁处理、处理机调度等。 二、内存管理 三、文件管理 四、设备管理 主要包括缓冲管理、设备分配、设备处理、虛拟设备等。 1.3 系统调用如果一个进程在用户态需要使用内核态的功能,就进行系统调用从而陷入内核,由操作系统代为完成。
1.4 大内核和微内核一、大内核 二、微内核 在微内核结构下,操作系统被划分成小的、定义良好的模块,只有微内核这一个模块运行在内核态,其余模块运行在用户态。 1.5 中断分类一、外中断 二、异常 三、陷入 2 进程管理2.1 进程与线程一、进程 下图显示了4个程序创建了4个进程,这4 个进程可以并发地执行。 一个进程中可以有多个线程,它们共享进程资源。 QQ和浏览器是两个进程,浏览器进程里面有很多线程,例如HTTP请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起HTTP请求时,浏览器还可以响应用户的其它事件。
类似地,在进行进程切换时,涉及当前执行进程CPU环境的保存及新调度进程CPU环境的设置,而线程切换时只需保存和设置少量寄存器内容,开销很小。 2.2 进程状态的切换
应该注意以下内容: (1)只有就绪态和运行态可以相互转换,其它的都是单向转换。就绪状态的进程通过调度算法从而获得 CPU 时间,转为运行状态;而运行状态的进程,在分配给它的 CPU 时间片用完之后就会转为就绪状态,等待下一次调度。 2.3 进程调度算法不同环境的调度算法目标不同,因此需要针对不同环境来讨论调度算法。 2.3.1 批处理系统批处理系统没有太多的用户操作,在该系统中,调度算法目标是保证吞吐量和周转时间(从提交到终止的时间)。 一、先来先服务 first-come first-serverd(FCFS) 非抢占式的调度算法,按照请求的顺序进行调度。 有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长。 二、短作业优先 shortest job first(SJF) 非抢占式的调度算法,按估计运行时间最短的顺序进行调度。 长作业有可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。 三、最短剩余时间优先 shortest remaining time next(SRTN) 最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度。当一个新的作业到达时,其整个运行时间与当前进程的剩余时间作比较。如果新的进程需要的时间更少,则挂起当前进程,运行新的进程。否则新的进程等待。 2.3.2 交互式系统交互式系统有大量的用户交互操作,在该系统中调度算法的目标是快速地进行响应。 一、时间片轮转 时间片轮转算法的效率和时间片的大小有很大关系: (1)因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频繁,在进程切换上就会花过多时间。 三、多级反馈队列 多级队列是为这种需要连续执行多个时间片的进程考虑,它设置了多个队列,每个队列时间片大小都不同,例如 1,2,4,8,…。进程在第一个队列没执行完,就会被移到下一个队列。这种方式下,之前的进程只需要交换 7 次。 每个队列优先权也不同,最上面的优先权最高。因此只有上一个队列没有进程在排队,才能调度当前队列上的进程。 可以将这种调度算法看成是时间片轮转调度算法和优先级调度算法的结合。 2.3.3 实时系统实时系统要求一个请求在一个确定时间内得到响应。 分为硬实时和软实时,前者必须满足绝对的截止时间,后者可以容忍一定的超时。 2.4 进程同步一、临界区 为了互斥访问临界资源,每个进程在进入临界区之前,需要先进行检查。 二、同步与互斥 三、信号量 down : 如果信号量大于0 ,执行-1操作;如果信号量等于0,进程睡眠,等待信号量大于0; up :对信号量执行+1操作,唤醒睡眠的进程让其完成down操作。 down和up操作需要被设计成原语,不可分割,通常的做法是在执行这些操作的时候屏蔽中断。 如果信号量的取值只能为0或者1,那么就成为了互斥量(Mutex) ,0表示临界区已经加锁,1表示临界区解锁。 问题描述:使用一个缓冲区来保存物品,只有缓冲区没有满,生产者才可以放入物品;只有缓冲区不为空,消费者才可以拿走物品。 因为缓冲区属于临界资源,因此需要使用一个互斥量 mutex 来控制对缓冲区的互斥访问。 为了同步生产者和消费者的行为,需要记录缓冲区中物品的数量。数量可以使用信号量来进行统计,这里需要使用两个信号量:empty 记录空缓冲区的数量,full 记录满缓冲区的数量。其中,empty 信号量是在生产者进程中使用,当 empty 不为 0 时,生产者才可以放入物品;full 信号量是在消费者进程中使用,当 full 信号量不为 0 时,消费者才可以取走物品。 注意,不能先对缓冲区进行加锁,再测试信号量。也就是说,不能先执行 down(mutex) 再执行 down(empty)。如果这么做了,那么可能会出现这种情况:生产者对缓冲区加锁后,执行 down(empty) 操作,发现 empty = 0,此时生产者睡眠。消费者不能进入临界区,因为生产者对缓冲区加锁了,消费者就无法执行 up(empty) 操作,empty 永远都为 0,导致生产者永远等待下,不会释放锁,消费者因此也会永远等待下去。 使用信号量机制实现的生产者消费者问题需要客户端代码做很多控制,而管程把控制的代码独立出来,不仅不容易出错,也使得客户端代码调用更容易。 c 语言不支持管程,下面的示例代码使用了类 Pascal 语言来描述管程。示例代码的管程提供了 insert() 和 remove() 方法,客户端代码通过调用这两个方法来解决生产者 - 消费者问题。 管程有一个重要特性:在一个时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程,否则其它进程永远不能使用管程。 管程引入了 条件变量 以及相关的操作:wait() 和 signal() 来实现同步操作。对条件变量执行 wait() 操作会导致调用进程阻塞,把管程让出来给另一个进程持有。signal() 操作用于唤醒被阻塞的进程。 使用管程实现生产者 - 消费者问题
2.5 经典同步问题生产者和消费者问题前面已经讨论过了。 2.5.1 哲学家进餐问题
下面是一种错误的解法,如果所有哲学家同时拿起左手边的筷子,那么所有哲学家都在等待其它哲学家吃完并释放自己手中的筷子,导致死锁。
2.5.2 读者-写者问题允许多个进程同时对数据进行读操作,但是不允许读和写以及写和写操作同时发生。
2.6 进程通信进程同步与进程通信很容易混淆,它们的区别在于: 进程通信是一种手段,而进程同步是一种目的。也可以说,为了能够达到进程同步的目的,需要让进程进行通信,传输一些进程同步所需要的信息。 一、管道
二、FIFO
FIFO 常用于客户 - 服务器应用程序中,FIFO 用作汇聚点,在客户进程和服务器进程之间传递数据。 五、共享存储 需要使用信号量用来同步对共享存储的访问。 多个进程可以将同一个文件映射到它们的地址空间从而实现共享内存。另外 XSI 共享内存不是使用文件,而是使用内存的匿名段。 六、套接字 3 内存管理3.1 虚拟内存虚拟内存的目的是为了让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。 为了更好的管理内存,操作系统将内存抽象成地址空间。每个程序拥有自己的地址空间,这个地址空间被分割成多个块,每一块称为一页。这些页被映射到物理内存,但不需要映射到连续的物理内存,也不需要所有页都必须在物理内存中。当程序引用到不在物理内存中的页时,由硬件执行必要的映射,将缺失的部分装入物理内存并重新执行失败的指令。 从上面的描述中可以看出,虚拟内存允许程序不用将地址空间中的每一页都映射到物理内存,也就是说一个程序不需要全部调入内存就可以运行,这使得有限的内存运行大程序成为可能。例如有一台计算机可以产生16位地址,那么一个程序的地址空间范围是0~64K。该计算机只有32KB的物理内存,虚拟内存技术允许该计算机运行一个64K大小的程序。 3.2 分页系统地址映射内存管理单元(MMU)管理着地址空间和物理内存的转换,其中的页表(Page table)存储着页(程序地址空间)和页框(物理内存空间)的映射表。 一个虚拟地址分成两个部分,一部分存储页面号,一部分存储偏移量。 下图的页表存放着 16 个页,这 16 个页需要用 4 个比特位来进行索引定位。例如对于虚拟地址(0010 000000000100),前 4 位是存储页面号 2,读取表项内容为(110 1),页表项最后一位表示是否存在于内存中,1 表示存在。后 12 位存储偏移量。这个页对应的页框的地址为 (110 000000000100)。 3.3 页面置换算法在程序运行过程中,如果要访问的页面不在内存中,就发生缺页中断从而将该页调入内存中。此时如果内存已无空闲空间,系统必须从内存中调出一个页面到磁盘对换区中来腾出空间。 页面置换算法和缓存淘汰策略类似,可以将内存看成磁盘的缓存。在缓存系统中,缓存的大小有限,当有新的缓存到达时,需要淘汰一部分已经存在的缓存,这样才有空间存放新的缓存数据。 页面置换算法的主要目标是使页面置换频率最低(也可以说缺页率最低)。 一、最佳 OPT, Optimal replacement algorithm 所选择的被换出的页面将是最长时间内不再被访问,通常可以保证获得最低的缺页率。 是一种理论上的算法,因为无法知道一个页面多长时间不再被访问。 举例:一个系统为某进程分配了三个物理块,并有如下页面引用序列:
开始运行时,先将 7, 0, 1 三个页面装入内存。当进程要访问页面 2 时,产生缺页中断,会将页面 7 换出,因为页面 7 再次被访问的时间最长。 二、最近最久未使用 LRU, Least Recently Used 虽然无法知道将来要使用的页面情况,但是可以知道过去使用页面的情况。LRU 将最近最久未使用的页面换出。 为了实现 LRU,需要在内存中维护一个所有页面的链表。当一个页面被访问时,将这个页面移到链表表头。这样就能保证链表表尾的页面是最近最久未访问的。 因为每次访问都需要更新链表,因此这种方式实现的 LRU 代价很高。
三、最近未使用 每个页面都有两个状态位:R 与 M,当页面被访问时设置页面的 R=1,当页面被修改时设置 M=1。其中 R 位会定时被清零。可以将页面分成以下四类:
当发生缺页中断时,NRU 算法随机地从类编号最小的非空类中挑选一个页面将它换出。 NRU 优先换出已经被修改的脏页面(R=0,M=1),而不是被频繁使用的干净页面(R=1,M=0)。 四、先进先出 选择换出的页面是最先进入的页面。 该算法会将那些经常被访问的页面换出,导致缺页率升高。 五、第二次机会算法 FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问题,对该算法做一个简单的修改: 当页面被访问 (读或写) 时设置该页面的 R 位为 1。需要替换的时候,检查最老页面的 R 位。如果 R 位是 0,那么这个页面既老又没有被使用,可以立刻置换掉;如果是 1,就将 R 位清 0,并把该页面放到链表的尾端,修改它的装入时间使它就像刚装入的一样,然后继续从链表的头部开始搜索。 六、时钟 第二次机会算法需要在链表中移动页面,降低了效率。时钟算法使用环形链表将页面连接起来,再使用一个指针指向最老的页面。 3.4 分段虚拟内存采用的是分页技术,也就是将地址空间划分成固定大小的页,每一页再与内存进行映射。 下图为一个编译器在编译过程中建立的多个表,有 4 个表是动态增长的,如果使用分页系统的一维地址空间,动态增长的特点会导致覆盖问题的出现。 分段的做法是把每个表分成段,一个段构成一个独立的地址空间。每个段的长度可以不同,并且可以动态增长。 3.5 段页式程序的地址空间划分成多个拥有独立地址空间的段,每个段上的地址空间划分成大小相同的页。这样既拥有分段系统的共享和保护,又拥有分页系统的虚拟内存功能。 3.6 分页与分段的比较(1)对程序员的透明性:分页透明,但是分段需要程序员显式划分每个段。 4 设备管理4.1 磁盘结构(1)盘面(Platter):一个磁盘有多个盘面; 4.2 磁盘调度算法读写一个磁盘块的时间的影响因素有: 一、先来先服务 二、最短寻道时间优先 虽然平均寻道时间比较低,但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近,那么在等待的磁道请求会一直等待下去,也就是出现饥饿现象。具体来说,两端的磁道请求更容易出现饥饿现象。 三、电梯算法 电梯算法(扫描算法)和电梯的运行过程类似,总是按一个方向来进行磁盘调度,直到该方向上没有未完成的磁盘请求,然后改变方向。 因为考虑了移动方向,因此所有的磁盘请求都会被满足,解决了SSTF的饥饿问题。 5 链接5.1 编译系统以下是一个hello.c程序:
这个过程大致如下:
5.2 静态链接静态链接器以一组可重定位目标文件为输入,生成一个完全链接的可执行目标文件作为输出。链接器主要完成以下两个任务: 5.3 目标文件可执行目标文件:可以直接在内存中执行; 5.4 动态链接静态库有以下两个问题: 共享库是为了解决静态库的这两个问题而设计的,在Linux系统中通常用.so后缀来表示,Windows系统上它们被称为DLL。它具有以下特点: (1)在给定的文件系统中一个库只有一个文件,所有引用该库的可执行目标文件都共享这个文件,它不会被复制到引用它的可执行文件中; 6 死锁6.1 必要条件
主要有以下四种处理方法:
6.2 鸵鸟策略把头埋在沙子里,假装根本没发生问题。 6.3 死锁检测与死锁恢复不试图阻止死锁,而是当检测到死锁发生时,采取措施进行恢复。 每种类型一个资源的死锁检测算法是通过检测有向图是否存在环来实现,从一个节点出发进行深度优先搜索,对访问过的节点进行标记,如果访问了已经标记的节点,就表示有向图存在环,也就是检测到死锁的发生。 二、每种类型多个资源的死锁检测
进程P1和P2所请求的资源都得不到满足,只有进程P3可以,让P3执行,之后释放P3拥有的资源,此时A = (2 2 2 0)。P2可以执行,执行后释放P2拥有的资源,A = (4 2 2 1) 。P1也可以执行。所有进程都可以顺利执行,没有死锁。 算法总结如下: 三、死锁恢复 6.4 死锁预防在程序运行之前预防发生死锁。 二、破坏占有和等待条件 三、破坏不可抢占条件 四、破坏环路等待 6.5 死锁避免在程序运行时避免发生死锁。 图a的第二列Has表示已拥有的资源数,第三列Max表示总共需要的资源数,Free表示还有可以使用的资源数。从图a开始出发,先让B拥有所需的所有资源(图 b),运行结束后释放B,此时Free变为5(图 c);接着以同样的方式运行C和A,使得所有进程都能成功运行,因此可以称图a所示的状态时安全的。 定义:如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每一个进程运行完毕,则称该状态是安全的。 安全状态的检测与死锁的检测类似,因为安全状态必须要求不能发生死锁。下面的银行家算法与死锁检测算法非常类似,可以结合着做参考对比。 二、单个资源的银行家算法
三、多个资源的银行家算法
检查一个状态是否安全的算法如下: |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 15:24:52- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |