操作系统总结知识 操作系统总结教程
你还在为不知道操作系统总结知识而不知所措么?下面来是小编为大家收集的操作系统总结知识,欢迎大家阅读:
操作系统总结知识
第一章 操作系统引论
系统的目标:有效性(提高资源利用率和系统吞吐量)、方便性、可扩充性、开放性。
有效性和方便性是操作系统最重要两个目标。
操作系统的作用:
(1) OS作为用户与计算机硬件系统之间的接口
(2) OS作为计算机系统资源的管理者(处理器、存储器、I/O设备、数据程序)
(3) OS实现了对计算机资源的抽象(在硬件上覆盖I/O设备、文件和窗口管理软件,即虚拟机)
OS的发展过程:无操作系统的计算机系统→单道批处理系统→多道批处理系统→分时系统→实时系统→微机操作系统
操作系统的基本特征:
(1) 并发性(两个或多个事件在同一时间间隔内发生;进入进程和线程)
(2) 共享性(系统中资源可供内存中多个并发执行的进程(线程)共同使用,方式为互斥共享方式和同时访问方式)
(3) 虚拟性(通过某种技术把一个物理实体变为若干个逻辑上的对应物。方式:时分复用技术和空分复用技术)
(4) 异步性(进程以不可预知的速度向前推进,多道程序设计固有的特点)
OS的主要功能:
(1) 处理机管理(进程管理)功能;(主要包括创建和撤销进程、协调诸进程的运行、实现进程间信息交换、把处理机分配给进程。进程同步机制功能是协调多个进程的运行,分为竞争和协作两种方式,实现进程同步常用的及时是信号量机制。调度包括作业调度和进程调度两步。)
(2) 存储器管理功能;(内存分配、内存保护、地址映射和内存扩充等功能。内存分配有动态和静态两方式。内容扩充的功能是请求调入和置换)
(3) 设备管理功能(缓冲管理、设备分配、设备处理和虚拟设备。缓冲管理包括单、双、公用缓冲机制。设备处理的人物是实现CPU和设备控制器之间的通信)
(4) 文件管理功能;(文件存储空间管理、目录管理、文件读写管理、共享保护功能)
(5) 操作系统与用户之间的接口;(用户接口和程序接口)
第二章 进程管理
进程与线程的基本概念
1) 进程是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量。
2) 线程是为了减少程序在并发执行时所付出的空间开销,是OS具有更好的并发性。
进程和线程的区别
1) 调度:线程作为调度和分派的基本单位;进程作为资源拥有的基本单位。
2) 并发性:进程之间可以并发执行,进程中的诸线程之间也可并发执行。
3) 拥有资源:进程拥有资源,线程无资源,但可以访问所属进程的资源
4) 系统开销:创建可撤销进程的代价比创建和撤销线程的代价大的多。
前趋图是描述进程之间执行的前后关系的。
进程的特征:
1) 结构特征;由程序段、相关的数据项和PCB三部分构成了进程实体。
2) 动态性;指从创建、调度执行到撤销的过程是动态的。
3) 并发性;
4) 独立性;因为有PCB,可以独立运行、独立分配资源、独立接受调度等功能
5) 异步性;各进程按各自独立、不可预知的速度向前推进。
进程的三种基本状态:
1) 就绪状态;处CPU外,已占有其他必要的资源的进程
2) 执行状态;
3) 阻塞状态;因事故是正在执行的进程停止,并让出CPU。
信号量机制是一种卓有成效的进程同步工具。包括整形信号量、记录型信号量、AND型信号量、信号量集。
第三章 处理机调度与死锁
批量型作业通常需要经历作业调度(高级调度或长程调度)和进程调度(低级调度和短程调度)两个过程后方能获得处理机。
处理机调度层次
1) 高级调度:把外存上处于后备队列中的那些作业调入内存。
2) 低级调度:它决定就绪队列中的哪个进程将获得处理机,然后由分派程序执行把处理机分配给该进程的操作。对象是进程。功能是:保存处理机现场信息(PCB);按某种算法选取进程;把处理器分配给进程。方式分为非抢占方式和抢占方式。
3) 中级调度:内存中不能有太多的进程,把进程从内存移到外存,当内存有足够空间时,再将合适的进程换入内存,等待进程调度。目的是提高内存利用率和系统吞吐量。
死锁:多个进程在运行过程中因争夺资源而造成的一种僵局。
活锁:多个进程在运行工程中因相互谦让而造成的一种僵局。
产生死锁的原因
1) 竞争资源
2) 进程间推进顺序非法
产生死锁的必要条件
1) 互斥条件:临界资源的互斥访问
2) 请求和保持条件:占着自己的资源不放,又去请求别人的
3) 不剥夺条件:进程没有完成则不是放占有的资源
4) 环路等待条件:发生死锁指必然存在一个资源环形链。
处理死锁的基本方法
1) 预防死锁
2) 避免死锁
3) 检测和解除死锁
安全序列:是指系统能够找到一个进程顺序(P1、P2……Pn),来为每个进程Pi分配所需资源,知道满足每个进程的最大需求,是每个进程能够顺利完成,则P1、P2……Pn即为安全状态。
用资源分配图对死锁进行检测,消去途中的所有边,若节点为孤立节点,则为可完全简化。
死锁的解除
1) 剥夺资源:从其他进程剥夺足够数量的资源给死锁进程,以解除死锁状态
2) 撤销进程:一种方法是夭折全部进程;另一种方法是按某个顺序逐个撤销进程,知道死锁状态被解除。
第四章 存储器管理
连续分配方式:一个用户程序分配一个连续的内存空间
1) 单一连续分配:一个程序装入其他程序就不允许被装入。只是用于单用户单任务的OS中。
2) 固定分区分配:把内存分为若干个固定大小的区域,每个分区装入一个作业,允许并发执行。
3) 动态分区分配:根据实际需要,动态地为之分配内存空间。
4) 动态重定位分区分配:通过重定位寄存器把相对地址转化成物理地址,此转化过程是在程序执行期间,随着每条指令或数据的访问自动进行的,故称为动态重定位。
分区分配算法
1) 首次适应算法(以地址递增次序访问)
2) 循环首次适应算法(从上一次分配处开始查找)
3) 最佳适应算法(小内存到大内存依次查找)
4) 最坏适应算法(每次分配从大内存开始割让)
5) 快速适应算法(对空闲分区进行分类,并建立索引表,选最适合的控件分配给请求的进程)
对换:把暂时不运行的程序调到外存,需要时再调到内存。
地址变换机制:将用户地址空间中的逻辑地址变换为内存空间中的物理地址。
引入分段存储管理方式的目的,则主要是为了满足用户在编程和使用上多方面的要求。
段表是用于实现从逻辑段到物理内存区的映射。
分页和分段的主要区别
1) 两者都采用离散分配方式,且都要通过地址应设机构来实现地址变换。
2) 页是信息的物理单位,分页是为了有效的管理内存;段是逻辑单位,分段是为了维护信息完整性和独立性。
3) 页的大小固定且由系统决定,段的长度不固定,决定于用户编写的程序。
4) 分页的作业地址空间是一维的,而分段的作业地址空间是二维的。
段页式存储管理方式的原理:分段和分页相结合,先将用户程序分成若干个段,再把每个段分成若干个页,并为每个段赋予一个段名。其地质结构由段号、段内页号和页内地址组成。
页面置换算法有:最佳置换算法、先进先出置换算法、最近最久未使用置换算法、Clock置换算法。
第五章 设备管理
I/O系统是用于实现数据输入、输出及数据存储的系统。
I/O设备类型:
1) 特性:存储设备;输入/输出设备。
2) 传输速率:低速设备;中速设备;高速设备。
3) 信息交换的单位分类:块设备;字符设备。
4) 共享属性:独占设备;共享设备;虚拟设备。
设备与控制器之间的接口:
1) 数据信号线:设备和设备控制器之间传送数据信号
2) 控制信号线:设备控制器向I/O设备发送控制信号的通路
3) 状态信号线:传送指示设备当前状态的信号。
设备控制器
主要职责是控制一个或多个I/O设备,以实现I/O设备和计算机之间的数据交换。是CPU和I/O设备的接口,他接受CPU指令去控制I/O设备工作,使减轻处理机的工作量。
设备控制器包括控制字符设备控制器和控制块设备的控制器。
设备控制器的基本功能
1) 接受和识别命令
2) 数据交换
3) 标识和报告设备的状态
4) 地址识别(CPU通过地质控制设备)
5) 数据缓冲
6) 差错控制
I/O通道是一种特殊的处理机,它具有执行I/O指令的能力,可以控制I/O操作。类型分为:字节多路通道、数组选择通道、数组多路通道。
解决“瓶颈”问题的最有效的方法是增加设备到主机间的通路而不增加通道。
I/O控制方式
1) 程序I/O方式
2) 中断驱动I/O控制方式
3) 直接存储器访问(DMA)I/O控制方式
4) I/O通道控制方式
SPOOLing技术
通过SPOOLing技术便可将一台物理I/O设备虚拟为多台逻辑I/O设备,同样允许多个用户共享一台物理I/O设备。
Spooling系统的组成
输入井和输入井;输入缓冲区和输出缓冲区;输入进程和输出进程。
SPOOLing系统的特点
1) 提高了I/O的速度
2) 将独占设备改造为共享设备
3) 实现了虚拟设备功能
磁盘调度
磁盘调度的主要目标是使磁盘的平均寻道时间最少。
常用的磁盘调度算法
1) 先来先服务(适合进程较少的场合)
2) 最短寻道时间优先(要访问的磁道与当前磁头所在磁道距离最近。会导致进程“饥饿”现象)
3) 扫描算法(考虑访问的磁道与当前磁头所在磁道距离最近和磁头当前移动的方向)
4) 循环扫描算法(规定磁头单向移动)
5) NSPetpSCAN和FSCAN调度算法
第六章 文件管理
文件逻辑结构的类型
1) 有结构文件(由一个以上的记录构成的文件,又称记录式文件)
2) 无结构文件(由字符流构成的文件,又称流式文件)
记录式文件的长度分为定长记录和变长记录。
记录文件又分为顺序文件、索引文件、索引顺序文件。
大量的数据结构而后数据库是采用有结构的文件形式
而大量的源代码、可执行文件、库函数等采用无结构文件。
顺序文件的优缺点
1) 适合进行批量存取
2) 存取效率是所有逻辑文件中最高的
3) 也只有顺序文件才能存储在磁带上,并能有效的工作
4) 不适合查找或修改单个记录
5) 增加或删除一个记录时比较困难
索引文件的缺点:除了有主文件外,还须配置一张索引表,而且每个记录都要有一个索引表,因此提高了存储费用。
对已直接文件,检索时可以根据记录键值直接获得指定记录的物理地址。
哈希文件是键值通过Hash函数指向目录表,该表目的内容指向记录所在的物理块。
外存分配方式:连续分配、连接分配和索引分配三种。
连续分配的优缺点
1) 顺序访问容易
2) 顺序访问速度快
缺点:
1) 要求有连续的存储空间
2) 必须实现知道文件的长度
链接分配中的链接方式分为隐式链接和显式链接。
为新建文件分配存储空间的方式分为连续和离散的分配方式。前置具有较高的文件访问速度,但可能产生较多的外存零头。后者能有效的利用外存空间,但访问速度较慢。无论哪种方式,存储空间的基本分配单位都是磁盘块而非字节。
文件存储空间管理的方法
1) 空闲表法和空闲链表法
2) 位示图法
3) 成组链接法
空闲表法和空闲链表法都不适用于大型文件系统可使用成组链接法。
常见面试题:
1、进程是并发过程中程序的执行过程
2、进程的特征:结构特征动态性并发性独立性异步性
3、临界区指在每个进程中访问临界资源的那段代码
4,现在操作系统中申请资源的基本单位是进程,在CPU得到执行的基本单位是线程,进程是由程序段、数据段、PCB组成的
5,对临界资源应采取互斥访问方式来实现共享
6,P.V操作是一种低级进程通信原语
7,对于记录性信号量,在执行一次P操作时,信号量的值应当减1,当其值为小于0时进程应阻塞;在执行V操作时,信号量的值应当加1;当其值小于等于0时,应唤醒阻塞队列中的进程。
8,N个进程共享某一临界资源,(n-1)~1
9,短作业优先算法,T1<T2<T3平均周转时间为:T1+2XT2/3+T3/3
10,响应比Rp=(等待时间+要求服务时间)/要求服务器时间=响应时间/要求服务时间
11死锁是指多个进程在运行过程中因争夺资源,而造成的一种僵局,当进程处于这种僵局状态时,若无外力作用,他们都将无法再向前推进。
死锁的避免是根据防止系统进入不安全状态。
产生死锁的根本原因是资源分配不当和资源数量不足,发生死锁的四个必要条件是:互斥条件,请求和保持条件,不剥夺条件和环路等待条件,银行家算法用于避免死锁
12,如果系统中有N个进程,最多为(N-1)个
13,若系统采用轮转法调度进程系统采用的是剥夺式调度
14,既考虑作业等待时间,又考虑作业执行时间,的调度算法是响应比优先调度算法
15,资源的有序分配策略可以破坏死锁的“循环等待”
16,并非所有的不安全状态都必然会转为死锁状态,但当系统进图不安全按状态后变有可能进入死锁状态,
17,重定位:在作业地址空间中使用的逻辑地址变为内存物理地址
18,支持程序放在不连续内存中储存管理方法有分取式分配,分段式分配,段页式分配页式存储主要特点是不要将作业同时全部装入到主存的的连续区域
19,适合多道程序运行的存储管理中,存储保护是为了防止各道作业的相互干扰
20,采用页式存储管理时,重定位的工作由地址转换机
21,段页式存储管理中的地址映像表是每个作业或进程一张段表,每个段一张页表
22,在虚拟页式存储管理方案中,完成将页面调入内存的工作的是缺页中断处理
23,分段管理和分页管理的主要区别是分页管理有存储保护,分段管理没有
24,在股低估分区分配中,可以不同但预先固定的
25,不使用中断机构的I/O控制方式是程序I/O方式
26,spooling技术能独占设备改造成可以共享的虚拟设备
27,磁盘防伪中把数据从磁盘读出,叫做传输时间
28,共享设备指同一时间内运行多个进程同时访问的设备
29,通过软件的功能扩充,把原来独占的设备爱造成若干个可共享的设备,虚拟设备
30,DMA方式如果I/O设备不通过CPU来完成
31,设备独立性用户程序独立于具体物理设备的一种特性
32,虚拟设备一个物理设备变换成多个对应的逻辑设备
33,通道是一种特殊的处理机,通道按传递数据的方式分为:字节多路通道,数组选择通道,数组多路通道
通道涉及的数据结构是设备控制器,控制器控制块,通道控制块,系统设备表
34,磁盘高速缓冲设在内存中,目的是提高I/O磁盘速度
35,磁盘空间的地址有盘面号,柱面号,扇区号组成。访问磁盘的时间有 寻道时间,旋转等待时间,读写时间
36,将系统段用参数翻译成设备操作命令的工作由设备无关的操作系统完成
37,向设备寄存器写入控制命令由设备驱动程序完成
38,寻找设备驱动程序由设备无关的操作系统软件完成
39,设备管理的功能是设备分配,缓冲区管理和实现物理I/O设备的操作
40,根据设备的固有属性特点,设备可分为独占设备,共享设备和虚拟设备
41,引入缓冲区技术可提高处理器执行程序和设备的输入输出操作的并行程序文件管理
42,物理文件的组织方式是由操作系统确定的,文件的顺序存取是按文件的逻辑号逐一存取
43,系统通过树形目录结构来解决重名问题
44,在UNIX操作系统中,把输入输出设备看做特殊文件
45,打开文件操作的主要工作是把指定的目录复制到内存指定区域
46,文件路径名是指从根目录到该文件所经历的路径中各符号名的集合
47,按逻辑结构划分,文件主要有两类:记录是文件,流式文件,文件系统的主要目的是实现对文件的按名存取
48连续结构文件必须采用连续分配方式,而链接结构文件和索引结构文件都可采取离散分配方式
49,文件系统中,若文件的物理结构采用连续结构有关文件的物理位置的信息包括首块地址和文件长度
50,位示图可用于磁盘空间管理,在文件系统中,为实现文件保护,一般采用口令,密码和访问控制
1、进程是具有独立功能程序在某个数据集合上的一次执行过程。线程是进程内的一个执行实体或执行单元。
进程和线程的区别:
(a)不同进程的地址空间是独立的,而同一进程内的线程共享同一地址空间。一个进程的线程在另一个进程内是不可见的。
(b) 在引入线程的操作系统中,进程是资源分配和调度的单位,线程是处理机调度和分配的单位,资源是分配给进程的,线程只拥有很少资源,因而切换代价比进程切换低。
2、死锁在多道程序系统中,当一组进程中的每个进程均无限期地等待被改组进程中的另一进程所占有且永远不会释放的资源,此时的系统处于死锁状态。
死锁产生的原因:
(a)系统提供的资源有限;
(b)进程推进顺序不当。
产生死锁的必要条件:互斥条件、不可剥夺条件、请求和保持条件、循环等待条件
3、执行如下访问页号序列: 1,2,3,4,1,2,5,1,2,3,4,5 试说明采用先进(1)FIFO: 9次(2)LRU:10次 (3)OPT:7次
4、什么是操作系统的基本功能?
1.处理机管理。在多道程序或多用户的情况下,要组织多个作业同时运行,就要解决对处理机分配调度策略、分配实施和资源回收等问题。
2.存储管理。存储管理的主要工作是对内部存储器进行分配、保护和扩充和管理。
3.设备管理。涉及到通道、控制器、输入输出设备的分配和管理以及设备独立性。
4.信息管理(文件系统管理) 是对系统的软件资源的管理。
5.用户接口。操作系统还为用户提供一个友好的用户接口。一般来说,操作系统提供两种方式的接口来为用户服务。
5、分级调度分为4级:
(1) 作业调度
(2) 交换调度
(3) 进程调度
(4) 线程调度。
6、试写出程序与进程的区别
(1)进程是一个动态概念,而程序是一个静态概念。
(2)进程具有并行特征,而程序不反映执行所以没有并行特征
(3)进程是竞争计算机系统资源的基本单位,而程序不反映执行也就不会竞争计算机系统资源
(4)不同的进程可以包含同一程序,只要该程序所对应的数据集不同。
7、页式管理的基本原理是什么?
(1)进程的虚拟空间被划分成长度相等的页。
(2)内存空间也按页的大小划分成长度相等的页面。
(3)采用请求调页或预调技术实现内外存储器的统一管理。
8、进程调度有哪些功能?
(1)记录系统中所有进程的执行情况。
(2)选择占有处理机的进程
(3)进行进程上下文切换
9、批处理操作系统、分时操作系统和实时操作系统的特点各是什么?
(1) 批处理操作系统的特点:成批处理,系统吞吐量高,资源利用率高,用户不能直接干预作业的执行。
(2)分时操作系统的特点:多路性、独立性、及时性、交互性。
(3)实时操作系统的特点:及时响应、快速处理;高可靠性和安全性;不要求系统资源利用率。
10、Windows下的内存是如何管理的?
Windows提供了3种方法来进行内存管理:虚拟内存,最适合用来管理大型对象或者结构数组;内存映射文件,最适合用来管理大型数据流(通常来自文件)以及在单个计算机上运行多个进程之间共享数据;内存堆栈,最适合用来管理大量的小对象。
Windows操纵内存可以分两个层面:物理内存和虚拟内存。
其中物理内存由系统管理,不允许应用程序直接访问,应用程序可见的只有一个2G地址空间,而内存分配是通过堆进行的。对于每个进程都有自己的默认堆,当一个堆创建后,就通过虚拟内存操作保留了相应大小的地址块(不占有实际的内存,系统消耗很小)。当在堆上分配一块内存时,系统在堆的地址表里找到一个空闲块(如果找不到,且堆创建属性是可扩充的,则扩充堆大小),为这个空闲块所包含的所有内存页提交物理对象(在物理内存上或硬盘的交换文件上),这时就可以访问这部分地址。提交时,系统将对所有进程的内存统一调配,如果物理内存不够,系统试图把一部分进程暂时不访问的页放入交换文件,以腾出部分物理内存。释放内存时,只在堆中将所在的页解除提交(相应的物理对象被解除),继续保留地址空间。
如果要知道某个地址是否被占用/可不可以访问,只要查询此地址的虚拟内存状态即可。如果是提交,则可以访问。如果仅仅保留,或没保留,则产生一个软件异常。此外,有些内存页可以设置各种属性。如果是只读,向内存写也会产生软件异常。
11、Windows消息调度机制是(C)
A)指令队列;B)指令堆栈;C)消息队列;D)消息堆栈
解析:
处理消息队列的顺序。首先Windows绝对不是按队列先进先出的次序来处理的,而是有一定优先级的。优先级通过消息队列的状态标志来实现的。首先,最高优先级的是别的线程发过来的消息(通过sendmessage);其次,处理登记消息队列消息;再次处理QS_QUIT标志,处理虚拟输入队列,处理wm_paint;最后是wm_timer。
12、描述实时系统的基本特性
在特定时间内完成特定的任务,实时性与可靠性。
所谓“实时操作系统”,实际上是指操作系统工作时,其各种资源可以根据需要随时进行动态分配。由于各种资源可以进行动态分配,因此,其处理事务的能力较强、速度较快。
13、中断和轮询的特点
对I/O设备的程序轮询的方式,是早期的计算机系统对I/O设备的一种管理方式。它定时对各种设备轮流询问一遍有无处理要求。轮流询问之后,有要求的,则加以处理。在处理I/O设备的要求之后,处理机返回继续工作。尽管轮询需要时间,但轮询要比I/O设备的速度要快得多,所以一般不会发生不能及时处理的问题。当然,再快的处理机,能处理的输入输出设备的数量也是有一定限度的。而且,程序轮询毕竟占据了CPU相当一部分处理时间,因此,程序轮询是一种效率较低的方式,在现代计算机系统中已很少应用。
程序中断通常简称中断,是指CPU在正常运行程序的过程中,由于预先安排或发生了各种随机的内部或外部事件,使CPU中断正在运行的程序,而转到为响应的服务程序去处理。
轮询——效率低,等待时间很长,CPU利用率不高。
中断——容易遗漏一些问题,CPU利用率高。
14、什么是临界区?如何解决冲突?
每个进程中访问临界资源的那段程序称为临界区,每次只准许一个进程进入临界区,进入后不允许其他进程进入。
(1)如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入;
(2)任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待;
(3)进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区;
(4)如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。
15、说说分段和分页
页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;或者说,分页仅仅是由于系统管理的需要,而不是用户的需要。
段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好的满足用户的需要。
页的大小固定且由系统确定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而一个系统只能有一种大小的页面。段的长度却不固定,决定于用户所编写的程序,通常由编辑程序在对源程序进行编辑时,根据信息的性质来划分。
分页的作业地址空间是一维的,即单一的线性空间,程序员只须利用一个记忆符,即可表示一地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。
16、说出你所知道的保持进程同步的方法?
进程间同步的主要方法有原子操作、信号量机制、自旋锁、管程、会合、分布式系统等。
17、Linux中常用到的命令
显示文件目录命令ls 如ls
改变当前目录命令cd 如cd /home
建立子目录mkdir 如mkdir xiong
删除子目录命令rmdir 如rmdir /mnt/cdrom
删除文件命令rm 如rm /ucdos.bat
文件复制命令cp 如cp /ucdos /fox
获取帮助信息命令man 如man ls
显示文件的内容less 如less mwm.lx
重定向与管道type 如type readme>>direct,将文件readme的内容追加到文direct中
18、Linux文件属性有哪些?(共十位)
-rw-r--r--那个是权限符号,总共是- --- --- ---这几个位。
第一个短横处是文件类型识别符:-表示普通文件;c表示字符设备(character);b表示块设备(block);d表示目录(directory);l表示链接文件(link);后面第一个三个连续的短横是用户权限位(User),第二个三个连续短横是组权限位(Group),第三个三个连续短横是其他权限位(Other)。每个权限位有三个权限,r(读权限),w(写权限),x(执行权限)。如果每个权限位都有权限存在,那么满权限的情况就是:-rwxrwxrwx;权限为空的情况就是- --- --- ---。
权限的设定可以用chmod命令,其格式位:chmod ugoa+/-/=rwx filename/directory。例如:
一个文件aaa具有完全空的权限- --- --- ---。
chmod u+rw aaa(给用户权限位设置读写权限,其权限表示为:- rw- --- ---)
chmod g+r aaa(给组设置权限为可读,其权限表示为:- --- r-- ---)
chmod ugo+rw aaa(给用户,组,其它用户或组设置权限为读写,权限表示为:- rw- rw- rw-)
如果aaa具有满权限- rwx rwx rwx。
chmod u-x aaa(去掉用户可执行权限,权限表示为:- rw- rwx rwx)
如果要给aaa赋予制定权限- rwx r-x r-x,命令为:
chmod u=rwx,Go=rx aaa
19、简术OSI的物理层Layer1,链路层Layer2,网络层Layer3的任务。
网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。
链路层:通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。
物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
20、什么是中断?中断时CPU做什么工作?
中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序。待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。
21、你知道操作系统的内容分为几块吗?什么叫做虚拟内存?他和主存的关系如何?内存管理属于操作系统的内容吗?
操作系统的主要组成部分:进程和线程的管理,存储管理,设备管理,文件管理。虚拟内存是一些系统页文件,存放在磁盘上,每个系统页文件大小为4K,物理内存也被分页,每个页大小也为4K,这样虚拟页文件和物理内存页就可以对应,实际上虚拟内存就是用于物理内存的临时存放的磁盘空间。页文件就是内存页,物理内存中每页叫物理页,磁盘上的页文件叫虚拟页,物理页+虚拟页就是系统所有使用的页文件的总和。
22、线程是否具有相同的堆栈?dll是否有独立的堆栈?
每个线程有自己的堆栈。
dll是否有独立的堆栈?这个问题不好回答,或者说这个问题本身是否有问题。因为dll中的代码是被某些线程所执行,只有线程拥有堆栈。如果dll中的代码是exe中的线程所调用,那么这个时候是不是说这个dll没有独立的堆栈?如果dll中的代码是由dll自己创建的线程所执行,那么是不是说dll有独立的堆栈?
以上讲的是堆栈,如果对于堆来说,每个dll有自己的堆,所以如果是从dll中动态分配的内存,最好是从dll中删除;如果你从dll中分配内存,然后在exe中,或者另外一个dll中删除,很有可能导致程序崩溃。
23、什么是缓冲区溢出?有什么危害?其原因是什么?
缓冲区溢出是指当计算机向缓冲区内填充数据时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。
危害:在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。
造成缓冲区溢出的主原因是程序中没有仔细检查用户输入的参数。
24、什么是死锁?其条件是什么?怎样避免死锁?
死锁的概念:在两个或多个并发进程中,如果每个进程持有某种资源而又都等待别的进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗地讲,就是两个或多个进程被无限期地阻塞、相互等待的一种状态。
死锁产生的原因主要是:
(1)系统资源不足;
(2) 进程推进顺序非法。
产生死锁的必要条件:
(1)互斥(mutualexclusion),一个资源每次只能被一个进程使用;
(2)不可抢占(nopreemption),进程已获得的资源,在未使用完之前,不能强行剥夺;
(3)占有并等待(hold andwait),一个进程因请求资源而阻塞时,对已获得的资源保持不放;
(4)环形等待(circularwait),若干进程之间形成一种首尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
死锁的解除与预防:理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。
死锁的处理策略:鸵鸟策略、预防策略、避免策略、检测与恢复策略。
附录:
1、什么是进程(Process)和线程(Thread)?有何区别?
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。
进程与应用程序的区别在于应用程序作为一个静态文件存储在计算机系统的硬盘等存储空间中,而进程则是处于动态条件下由操作系统维护的系统资源管理实体。
2、Windows下的内存是如何管理的?
Windows提供了3种方法来进行内存管理:虚拟内存,最适合用来管理大型对象或者结构数组;内存映射文件,最适合用来管理大型数据流(通常来自文件)以及在单个计算机上运行多个进程之间共享数据;内存堆栈,最适合用来管理大量的小对象。
Windows操纵内存可以分两个层面:物理内存和虚拟内存。
其中物理内存由系统管理,不允许应用程序直接访问,应用程序可见的只有一个2G地址空间,而内存分配是通过堆进行的。对于每个进程都有自己的默认堆,当一个堆创建后,就通过虚拟内存操作保留了相应大小的地址块(不占有实际的内存,系统消耗很小)。当在堆上分配一块内存时,系统在堆的地址表里找到一个空闲块(如果找不到,且堆创建属性是可扩充的,则扩充堆大小),为这个空闲块所包含的所有内存页提交物理对象(在物理内存上或硬盘的交换文件上),这时就可以访问这部分地址。提交时,系统将对所有进程的内存统一调配,如果物理内存不够,系统试图把一部分进程暂时不访问的页放入交换文件,以腾出部分物理内存。释放内存时,只在堆中将所在的页解除提交(相应的物理对象被解除),继续保留地址空间。
如果要知道某个地址是否被占用/可不可以访问,只要查询此地址的虚拟内存状态即可。如果是提交,则可以访问。如果仅仅保留,或没保留,则产生一个软件异常。此外,有些内存页可以设置各种属性。如果是只读,向内存写也会产生软件异常。
3、Windows消息调度机制是?
A)指令队列;B)指令堆栈;C)消息队列;D)消息堆栈
答案:C
处理消息队列的顺序。首先Windows绝对不是按队列先进先出的次序来处理的,而是有一定优先级的。优先级通过消息队列的状态标志来实现的。首先,最高优先级的是别的线程发过来的消息(通过sendmessage);其次,处理登记消息队列消息;再次处理QS_QUIT标志,处理虚拟输入队列,处理wm_paint;最后是wm_timer。
4、描述实时系统的基本特性
在特定时间内完成特定的任务,实时性与可靠性。
所谓“实时操作系统”,实际上是指操作系统工作时,其各种资源可以根据需要随时进行动态分配。由于各种资源可以进行动态分配,因此,其处理事务的能力较强、速度较快。
5、中断和轮询的特点
对I/O设备的程序轮询的方式,是早期的计算机系统对I/O设备的一种管理方式。它定时对各种设备轮流询问一遍有无处理要求。轮流询问之后,有要求的,则加以处理。在处理I/O设备的要求之后,处理机返回继续工作。尽管轮询需要时间,但轮询要比I/O设备的速度要快得多,所以一般不会发生不能及时处理的问题。当然,再快的处理机,能处理的输入输出设备的数量也是有一定限度的。而且,程序轮询毕竟占据了CPU相当一部分处理时间,因此,程序轮询是一种效率较低的方式,在现代计算机系统中已很少应用。
程序中断通常简称中断,是指CPU在正常运行程序的过程中,由于预先安排或发生了各种随机的内部或外部事件,使CPU中断正在运行的程序,而转到为响应的服务程序去处理。
轮询——效率低,等待时间很长,CPU利用率不高。
中断——容易遗漏一些问题,CPU利用率高。
6、什么是临界区?如何解决冲突?
每个进程中访问临界资源的那段程序称为临界区,每次只准许一个进程进入临界区,进入后不允许其他进程进入。
(1)如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入;
(2)任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待;
(3)进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区;
(4)如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。
7、说说分段和分页
页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;或者说,分页仅仅是由于系统管理的需要,而不是用户的需要。
段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好的满足用户的需要。
页的大小固定且由系统确定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而一个系统只能有一种大小的页面。段的长度却不固定,决定于用户所编写的程序,通常由编辑程序在对源程序进行编辑时,根据信息的性质来划分。
分页的作业地址空间是一维的,即单一的线性空间,程序员只须利用一个记忆符,即可表示一地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。
8、说出你所知道的保持进程同步的方法?
进程间同步的主要方法有原子操作、信号量机制、自旋锁、管程、会合、分布式系统等。
9、Linux中常用到的命令
显示文件目录命令ls 如ls
改变当前目录命令cd 如cd /home
建立子目录mkdir 如mkdir xiong
删除子目录命令rmdir 如rmdir /mnt/cdrom
删除文件命令rm 如rm /ucdos.bat
文件复制命令cp 如cp /ucdos /fox
获取帮助信息命令man 如man ls
显示文件的内容less 如less mwm.lx
重定向与管道type 如type readme>>direct,将文件readme的内容追加到文direct中
10、Linux文件属性有哪些?(共十位)
-rw-r--r--那个是权限符号,总共是- --- --- ---这几个位。
第一个短横处是文件类型识别符:-表示普通文件;c表示字符设备(character);b表示块设备(block);d表示目录(directory);l表示链接文件(link);后面第一个三个连续的短横是用户权限位(User),第二个三个连续短横是组权限位(Group),第三个三个连续短横是其他权限位(Other)。每个权限位有三个权限,r(读权限),w(写权限),x(执行权限)。如果每个权限位都有权限存在,那么满权限的情况就是:-rwxrwxrwx;权限为空的情况就是- --- --- ---。
权限的设定可以用chmod命令,其格式位:chmod ugoa+/-/=rwx filename/directory。例如:
一个文件aaa具有完全空的权限- --- --- ---。
chmod u+rw aaa(给用户权限位设置读写权限,其权限表示为:- rw- --- ---)
chmod g+r aaa(给组设置权限为可读,其权限表示为:- --- r-- ---)
chmod ugo+rw aaa(给用户,组,其它用户或组设置权限为读写,权限表示为:- rw- rw- rw-)
如果aaa具有满权限- rwx rwx rwx。
chmod u-x aaa(去掉用户可执行权限,权限表示为:- rw- rwx rwx)
如果要给aaa赋予制定权限- rwx r-x r-x,命令为:
chmod u=rwx,go=rx aaa
11、makefile文件的作用是什么?
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中。makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”。一旦写好,只需要一个make命令,整个工程完全自动编译,极大地提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具。一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
12、简术OSI的物理层Layer1,链路层Layer2,网络层Layer3的任务。
网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。
链路层:通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。
物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
13、什么是中断?中断时CPU做什么工作?
中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序。待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。
14、你知道操作系统的内容分为几块吗?什么叫做虚拟内存?他和主存的关系如何?内存管理属于操作系统的内容吗?
操作系统的主要组成部分:进程和线程的管理,存储管理,设备管理,文件管理。虚拟内存是一些系统页文件,存放在磁盘上,每个系统页文件大小为4K,物理内存也被分页,每个页大小也为4K,这样虚拟页文件和物理内存页就可以对应,实际上虚拟内存就是用于物理内存的临时存放的磁盘空间。页文件就是内存页,物理内存中每页叫物理页,磁盘上的页文件叫虚拟页,物理页+虚拟页就是系统所有使用的页文件的总和。
15、线程是否具有相同的堆栈?dll是否有独立的堆栈?
每个线程有自己的堆栈。
dll是否有独立的堆栈?这个问题不好回答,或者说这个问题本身是否有问题。因为dll中的代码是被某些线程所执行,只有线程拥有堆栈。如果dll中的代码是exe中的线程所调用,那么这个时候是不是说这个dll没有独立的堆栈?如果dll中的代码是由dll自己创建的线程所执行,那么是不是说dll有独立的堆栈?
以上讲的是堆栈,如果对于堆来说,每个dll有自己的堆,所以如果是从dll中动态分配的内存,最好是从dll中删除;如果你从dll中分配内存,然后在exe中,或者另外一个dll中删除,很有可能导致程序崩溃。
16、什么是缓冲区溢出?有什么危害?其原因是什么?
缓冲区溢出是指当计算机向缓冲区内填充数据时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。
危害:在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。
造成缓冲区溢出的主原因是程序中没有仔细检查用户输入的参数。
17、什么是死锁?其条件是什么?怎样避免死锁?
死锁的概念:在两个或多个并发进程中,如果每个进程持有某种资源而又都等待别的进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗地讲,就是两个或多个进程被无限期地阻塞、相互等待的一种状态。
死锁产生的原因主要是:? 系统资源不足;? 进程推进顺序非法。
产生死锁的必要条件:
(1)互斥(mutualexclusion),一个资源每次只能被一个进程使用;
(2)不可抢占(nopreemption),进程已获得的资源,在未使用完之前,不能强行剥夺;
(3)占有并等待(hold andwait),一个进程因请求资源而阻塞时,对已获得的资源保持不放;
(4)环形等待(circularwait),若干进程之间形成一种首尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
死锁的解除与预防:理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。
死锁的处理策略:鸵鸟策略、预防策略、避免策略、检测与恢复策略。
1、程序和进程
进程由两个部分组成:1)操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。2)地址空间。它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆分配空间。
定义
使用系统运行资源情况
程序
计算机指令的集合,它以文件的形式存储在磁盘上。程序是静态实体(passive Entity),在多道程序系统中,它是不能独立运行的,更不能与其他程序并发执行。
不使用【程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源】。
进程
通常被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动。
定义:进程是进程实体(包括:程序段、相关的数据段、进程控制块PCB)的运行过程,是系统进行资源分配和调度的一个独立单位。
使用【进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源。】
2、进程与线程
如果说操作系统引入进程的目的是为了提高程序并发执行,以提高资源利用率和系统吞吐量。那么操作系统中引入线程的目的,则是为了减少进程并发执行过程中所付出的时空开销,使操作系统能很好的并发执行。
进程process定义了一个执行环境,包括它自己私有的地址空间、一个句柄表,以及一个安全环境;线程则是一个控制流,有他自己的调用栈call stack,记录了它的执行历史。
线程由两个部分组成:1)线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。2)线程堆栈,它用于维护线程在执行代码时需要的所有参数和局部变量。当创建线程时,系统创建一个线程内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构。可以将线程内核对象视为由关于线程的统计信息组成的一个小型数据结构。
进程与线程的比较如下:
比较
进程
线程
活泼性
不活泼(只是线程的容器)
活泼
地址空间
系统赋予的独立的虚拟地址空间(对于32位进程来说,这个地址空间是4GB)
在进程的地址空间执行代码。线程只有一个内核对象和一个堆栈,保留的记录很少,因此所需要的内存也很少。因为线程需要的开销比进程少
调度
仅是资源分配的基本单位
独立调度、分派的基本单位
并发性
仅进程间并发(传统OS)
进程间、线程间并发
拥有资源
资源拥有的基本单位
基本上不拥有资源
系统开销
创建、撤销、切换开销大
仅保存少量寄存器内容,开销小。
3、进程同步
进程同步的主要任务:是对多个相关进程在执行次序上进行协调,以使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。
同步机制遵循的原则:
(1)空闲让进;
(2)忙则等待(保证对临界区的互斥访问);
(3)有限等待(有限代表有限的时间,避免死等);
(4)让权等待,(当进程不能进入自己的临界区时,应该释放处理机,以免陷入忙等状态)。
4、进程间的通信是如何实现的?
进程通信,是指进程之间的信息交换(信息量少则一个状态或数值,多者则是成千上万个字节)。因此,对于用信号量进行的进程间的互斥和同步,由于其所交换的信息量少而被归结为低级通信。
所谓高级进程通信指:用户可以利用操作系统所提供的一组通信命令传送大量数据的一种通信方式。操作系统隐藏了进程通信的实现细节。或者说,通信过程对用户是透明的。
高级通信机制可归结为三大类:
(1)共享存储器系统(存储器中划分的共享存储区);实际操作中对应的是“剪贴板”(剪贴板实际上是系统维护管理的一块内存区域)的通信方式,比如举例如下:word进程按下ctrl+c,在ppt进程按下ctrl+v,即完成了word进程和ppt进程之间的通信,复制时将数据放入到剪贴板,粘贴时从剪贴板中取出数据,然后显示在ppt窗口上。
(2)消息传递系统(进程间的数据交换以消息(message)为单位,当今最流行的微内核操作系统中,微内核与服务器之间的通信,无一例外地都采用了消息传递机制。应用举例:邮槽(MailSlot)是基于广播通信体系设计出来的,它采用无连接的不可靠的数据传输。邮槽是一种单向通信机制,创建邮槽的服务器进程读取数据,打开邮槽的客户机进程写入数据。
(3)管道通信系统(管道即:连接读写进程以实现他们之间通信的共享文件(pipe文件,类似先进先出的队列,由一个进程写,另一进程读))。实际操作中,管道分为:匿名管道、命名管道。匿名管道是一个未命名的、单向管道,通过父进程和一个子进程之间传输数据。匿名管道只能实现本地机器上两个进程之间的通信,而不能实现跨网络的通信。命名管道不仅可以在本机上实现两个进程间的通信,还可以跨网络实现两个进程间的通信。
同一机器两个进程间通信
跨网络通信
剪贴板Clipboard
可以
不可以
匿名管道Pipe
可以
不可以
命名管道(点对点单一通信,数据量可较大)Namedpipe
可以
可以
邮槽(一对多,数据量较小,424字节以下)Mailslot
可以
可以
5、线程同步
根据用户模式及内核模式下的同步方式的不同,分类及对比如下:
内核对象/
非内核对象
含义
缺点
适用
关键代码段(临界区)CriticalSection
非内核对象,工作在用户方式下,为用户模式对象
从程序代码的角度来控制线程的并发性
1.因为在等待进入关键代码段时无法设定超时值,所以其很容易进入死锁状态。2.不能跨进程使用。
单个进程中线程间的同步(同步速度快)
事件对象Event
内核对象
所有内核对象中最基本的。
速度较慢(相比用户模式实现线程同步)
多个进程间的各个线程间实现同步
互斥对象Mutex
内核对象
代表对一个资源的独占式访问
信号量
Semaphore
内核对象
使用计数器来控制程序对一个共享资源的访问
由于进程同步产生了一系列经典的同步问题“生产者-消费者”问题,“哲学家进餐”问题,“读者-写者”问题。
常见的操作系统使用的文件系统整理
文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法。也指用于存储文件的磁盘或分区,或文件系统种类。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:与文件管理有关软件、被管理文件以及实施文件管理所需数据结构。从系统角度来看,文件系统是对文件存储器空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。
【FAT】:
常PC机使用的文件系统是FAT16。像基于MS-DOS,Win 95等系统都采用了FAT16文件系统。在Win 9X下,FAT16支持的分区最大为2GB。我们知道计算机将信息保存在硬盘上称为“簇”的区域内。使用的簇越小,保存信息的效率就越高。在FAT16的情况下,分区越大簇就相应的要大,存储效率就越低,势必造成存储空间的浪费。并且随着计算机硬件和应用的不断提高,FAT16文件系统已不能很好地适应系统的要求。在这种情况下,推出了增强的文件系统FAT32。同FAT16相比,FAT32主要具有以下特点:
1、同FAT16相比FAT32最大的优点是可以支持的磁盘大小达到32G,但是不能支持小于512MB的分区。
*基于FAT32的Win 2000可以支持分区最大为32GB;而基于 FAT16的Win 2000支持的分区最大为4GB。
2、由于采用了更小的簇,FAT32文件系统可以更有效率地保存信息。如两个分区大小都为2GB,一个分区采用了FAT16文件系统,另一个分区采用了FAT32文件系统。采用FAT16的分区的簇大小为32KB,而FAT32分区的簇只有4KB的大小。这样FAT32就比FAT16的存储效率要高很多,通常情况下可以提高15%。
3、FAT32文件系统可以重新定位根目录和使用FAT的备份副本。另外FAT32分区的启动记录被包含在一个含有关键数据的结构中,减少了计算机系统崩溃的可能性。
【NTFS】:
NTFS文件系统是一个基于安全性的文件系统,是Windows NT所采用的独特的文件系统结构,它是建立在保护文件和目录数据基础上,同时照顾节省存储资源、减少磁盘占用量的一种先进的文件系统。使用非常广泛的Windows NT 4.0采用的就是NTFS 4.0文件系统,相信它所带来的强大的系统安全性一定给广大用户留下了深刻的印象。Win 2000采用了更新版本的NTFS文件系统??NTFS 5.0,它的推出使得用户不但可以像Win 9X那样方便快捷地操作和管理计算机,同时也可享受到NTFS所带来的系统安全性。
NTFS 5.0的特点主要体现在以下几个方面:
1、NTFS可以支持的分区(如果采用动态磁盘则称为卷)大小可以达到2TB。而Win 2000中的FAT32支持分区的大小最大为32GB。
2、NTFS是一个可恢复的文件系统。在NTFS分区上用户很少需要运行磁盘修复程序。NTFS通过使用标准的事物处理日志和恢复技术来保证分区的一致性。发生系统失败事件时,NTFS使用日志文件和检查点信息自动恢复文件系统的一致性。
3、NTFS支持对分区、文件夹和文件的压缩。任何基于Windows的应用程序对NTFS分区上的压缩文件进行读写时不需要事先由其他程序进行解压缩,当对文件进行读取时,文件将自动进行解压缩;文件关闭或保存时会自动对文件进行压缩。
4、NTFS采用了更小的簇,可以更有效率地管理磁盘空间。在Win 2000的FAT32文件系统的情况下,分区大小在2GB~8GB时簇的大小为4KB;分区大小在8GB~16GB时簇的大小为8KB;分区大小在16GB~32GB时,簇的大小则达到了16KB。而Win 2000的NTFS文件系统,当分区的大小在2GB以下时,簇的大小都比相应的FAT32簇小;当分区的大小在2GB以上时(2GB~2TB),簇的大小都为4KB。相比之下,NTFS可以比FAT32更有效地管理磁盘空间,最大限度地避免了磁盘空间的浪费。
5、在NTFS分区上,可以为共享资源、文件夹以及文件设置访问许可权限。许可的设置包括两方面的内容:一是允许哪些组或用户对文件夹、文件和共享资源进行访问;二是获得访问许可的组或用户可以进行什么级别的访问。访问许可权限的设置不但适用于本地计算机的用户,同样也应用于通过网络的共享文件夹对文件进行访问的网络用户。与FAT32文件系统下对文件夹或文件进行访问相比,安全性要高得多。另外,在采用NTFS格式的Win 2000中,应用审核策略可以对文件夹、文件以及活动目录对象进行审核,审核结果记录在安全日志中,通过安全日志就可以查看哪些组或用户对文件夹、文件或活动目录对象进行了什么级别的操作,从而发现系统可能面临的非法访问,通过采取相应的措施,将这种安全隐患减到最低。这些在FAT32文件系统下,是不能实现的。
6、在Win 2000的NTFS文件系统下可以进行磁盘配额管理。磁盘配额就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。设置磁盘配额后,可以对每一个用户的磁盘使用情况进行跟踪和控制,通过监测可以标识出超过配额报警阈值和配额限制的用户,从而采取相应的措施。磁盘配额管理功能的提供,使得管理员可以方便合理地为用户分配存储资源,避免由于磁盘空间使用的失控可能造成的系统崩溃,提高了系统的安全性。
7、NTFS使用一个“变更”日志来跟踪记录文件所发生的变更。
【Ext2】:
Ext2是 GNU/Linux 系统中标准的文件系统,其特点为存取文件的性能极好,对于中小型的文件更显示出优势,这主要得利于其簇快取层的优良设计。
其单一文件大小与文件系统本身的容量上限与文件系统本身的簇大小有关,在一般常见的 x86 电脑系统中,簇最大为 4KB,则单一文件大小上限为 2048GB,而文件系统的容量上限为 16384GB。
但由于目前核心 2.4 所能使用的单一分割区最大只有 2048GB,实际上能使用的文件系统容量最多也只有 2048GB。
至于Ext3文件系统,它属于一种日志文件系统,是对ext2系统的扩展。它兼容ext2,并且从ext2转换成ext3并不复杂。
【Ext3】:
Ext3是一种日志式文件系统,是对ext2系统的扩展,它兼容ext2。日志式文件系统的优越性在于:由于文件系统都有快取层参与运作,如不使用时必须将文件系统卸下,以便将快取层的资料写回磁盘中。因此每当系统要关机时,必须将其所有的文件系统全部shutdown后才能进行关机。
如果在文件系统尚未shutdown前就关机 (如停电) 时,下次重开机后会造成文件系统的资料不一致,故这时必须做文件系统的重整工作,将不一致与错误的地方修复。然而,此一重整的工作是相当耗时的,特别是容量大的文件系统,而且也不能百分之百保证所有的资料都不会流失。
为了克服此问题,使用所谓‘日志式文件系统 (Journal File System) ’。此类文件系统最大的特色是,它会将整个磁盘的写入动作完整记录在磁盘的某个区域上,以便有需要时可以回溯追踪。
由于资料的写入动作包含许多的细节,像是改变文件标头资料、搜寻磁盘可写入空间、一个个写入资料区段等等,每一个细节进行到一半若被中断,就会造成文件系统的不一致,因而需要重整。
然而,在日志式文件系统中,由于详细纪录了每个细节,故当在某个过程中被中断时,系统可以根据这些记录直接回溯并重整被中断的部分,而不必花时间去检查其他的部分,故重整的工作速度相当快,几乎不需要花时间。
【Ext4】:
Linux kernel 自 2.6.28 开始正式支持新的文件系统 Ext4。Ext4 是 Ext3 的改进版,修改了 Ext3 中部分重要的数据结构,而不仅仅像 Ext3 对 Ext2 那样,只是增加了一个日志功能而已。Ext4 可以提供更佳的性能和可靠性,还有更为丰富的功能:
1、与 Ext3 兼容。执行若干条命令,就能从 Ext3 在线迁移到 Ext4,而无须重新格式化磁盘或重新安装系统。原有 Ext3 数据结构照样保留,Ext4 作用于新数据,当然,整个文件系统因此也就获得了 Ext4 所支持的更大容量。
2、更大的文件系统和更大的文件。较之 Ext3 目前所支持的最大 16TB 文件系统和最大 2TB 文件,Ext4 分别支持 1EB(1,048,576TB, 1EB=1024PB, 1PB=1024TB)的文件系统,以及 16TB 的文件。
3、无限数量的子目录。Ext3 目前只支持 32,000 个子目录,而 Ext4 支持无限数量的子目录。
4、Extents。Ext3 采用间接块映射,当操作大文件时,效率极其低下。比如一个 100MB 大小的文件,在 Ext3 中要建立 25,600 个数据块(每个数据块大小为 4KB)的映射表。而 Ext4 引入了现代文件系统中流行的 extents 概念,每个 extent 为一组连续的数据块,上述文件则表示为“该文件数据保存在接下来的 25,600 个数据块中”,提高了不少效率。
5、多块分配。当写入数据到 Ext3 文件系统中时,Ext3 的数据块分配器每次只能分配一个 4KB 的块,写一个 100MB 文件就要调用 25,600 次数据块分配器,而 Ext4 的多块分配器“multiblock allocator”(mballoc) 支持一次调用分配多个数据块。
6、延迟分配。Ext3 的数据块分配策略是尽快分配,而 Ext4 和其它现代文件操作系统的策略是尽可能地延迟分配,直到文件在 cache 中写完才开始分配数据块并写入磁盘,这样就能优化整个文件的数据块分配,与前两种特性搭配起来可以显著提升性能。
7、快速 fsck。以前执行 fsck 第一步就会很慢,因为它要检查所有的 inode,现在 Ext4 给每个组的 inode 表中都添加了一份未使用 inode 的列表,今后 fsck Ext4 文件系统就可以跳过它们而只去检查那些在用的 inode 了。
8、日志校验。日志是最常用的部分,也极易导致磁盘硬件故障,而从损坏的日志中恢复数据会导致更多的数据损坏。Ext4 的日志校验功能可以很方便地判断日志数据是否损坏,而且它将 Ext3 的两阶段日志机制合并成一个阶段,在增加安全性的同时提高了性能。
9、“无日志”(No Journaling)模式。日志总归有一些开销,Ext4 允许关闭日志,以便某些有特殊需求的用户可以借此提升性能。
10、在线碎片整理。尽管延迟分配、多块分配和 extents 能有效减少文件系统碎片,但碎片还是不可避免会产生。Ext4 支持在线碎片整理,并将提供 e4defrag 工具进行个别文件或整个文件系统的碎片整理。
11、inode 相关特性。Ext4 支持更大的 inode,较之 Ext3 默认的 inode 大小 128 字节,Ext4 为了在 inode 中容纳更多的扩展属性(如纳秒时间戳或 inode 版本),默认 inode 大小为 256 字节。Ext4 还支持快速扩展属性(fast extended attributes)和 inode 保留(inodes reservation)。
12、持久预分配(Persistent preallocation)。P2P 软件为了保证下载文件有足够的空间存放,常常会预先创建一个与所下载文件大小相同的空文件,以免未来的数小时或数天之内磁盘空间不足导致下载失败。Ext4 在文件系统层面实现了持久预分配并提供相应的 API(libc 中的 posix_fallocate()),比应用软件自己实现更有效率。
13、默认启用 barrier。磁盘上配有内部缓存,以便重新调整批量数据的写操作顺序,优化写入性能,因此文件系统必须在日志数据写入磁盘之后才能写 commit 记录,若 commit 记录写入在先,而日志有可能损坏,那么就会影响数据完整性。Ext4 默认启用 barrier,只有当 barrier 之前的数据全部写入磁盘,才能写 barrier 之后的数据。(可通过 “mount -o barrier=0” 命令禁用该特性。)
【ZFS】:
ZFS源自于Sun Microsystems为Solaris操作系统开发的文件系统。ZFS是一个具有高存储容量、文件系统与卷管理概念整合、崭新的磁盘逻辑结构的轻量级文件系统,同时也是一个便捷的存储池管理系统。ZFS是一个使用CDDL协议条款授权的开源项目。
【HFS】:
1、HFS文件系统概念
分层文件系统(Hierarchical File System,HFS)是一种由苹果电脑开发,并使用在Mac OS上的文件系统。最初被设计用于软盘和硬盘,同时也可以在在只读媒体如CD-ROM上见到。
2、HFS文件系统开发过程
HFS首次出现在1985年9月17日,作为Macintosh电脑上新的文件系统。它取代只用于早期Mac型号所使用的平面文件系统Macintosh File System(MFS)。因为Macintosh电脑所产生的数据,比其它通常的文件系统,如DOS使用的FAT或原始Unix文件系统所允许存储的数据更多。苹果电脑开发了一种新式更适用的文件系统,而不是采用现有的规格。例如,HFS允许文件名最多有31个字符的长度,支持metadata和双分支(每个文件的数据和资源支分开存储)文件。
尽管HFS象其它大多数文件系统一样被视为专有的格式,因为只有它为大多数最新的操作系统提供了很好的通用解决方法以存取HFS格式磁盘。
在1998年,苹果电脑发布了HFS Plus,其改善了HFS对磁盘空间的地址定位效率低下,并加入了其它的改进。当前版本的Mac OS仍旧支持HFS,但从Mac OS X开始HFS卷不能作为启动用。
3、构成方式
分层文件系统把一个卷分为许多512字节的“逻辑块”。这些逻辑块被编组为“分配块”,这些分配块可以根据卷的尺寸包含一个或多个逻辑块。HFS对地址分配块使用16位数值,分配块的最高限制数量是65536。
组成一个HFS卷需要下面的五个结构:
1)卷的逻辑块0和1是启动块,它包含了系统启动信息。例如,启动时载入的系统名称和壳(通常是Finder)文件。
2)逻辑块2包含主目录块(Master Directory Block,简称MDB)。
3)逻辑块3是卷位图(Volume Bitmap)的启动块,它追踪分配块使用状态。
4)总目录文件(Catalog File)是一个包含所有文件的记录和储存在卷中目录的B*-tree。
5)扩展溢出文件(Extent Overflow File)是当最初总目录文件中三个扩展占用后,另外一个包含额外扩展记录的分配块对应信息的B*-tree。
内核怎样管理你的内存
在分析了进程的虚拟地址布局,我们转向内核以及他管理用户内存的机制。下图是gonzo的例子:
Linux进程在内核中是由task_struct进程描述符实现的,task_struct的mm字段指向内存描述符mm_struct,他是进程的一个内存执行摘要。如上图所示,mm_struct存储了内存各个段的开始和结束地址、进程所使用的内存页面数(rss代表常驻集合大小)、使用的虚拟地址空间总数等等。在内存描述符中我们也可以找到两个用于管理进程内层的字段:虚拟内存集合和页表。Gonzo的内存区域如下图:
每个虚拟内存区域(VMA)是一个虚拟地址空间上连续的区域;这些区域不会彼此覆盖。Vm_area_struct结构描述了一个内存区域,包括他的开始和技术地址、flags字段指定了他的行为和访问权限,vm_file字段指定了该区域映射的实际文件。一个没有映射文件的VMA成为匿名的。除了内存映射段以外,上面的每个内存段(堆、栈等等)相当于一个单独的VMA。这不是必须的,尽管在x86机器上通常是这样。VMA不会关心他在哪个段里面。
一个进程的所有VMA以两种方式存储在他的内存描述符中,一种是以链表的方式存放在mmap字段,以开始虚拟地址进行了排序,另一种是以红黑树的方式存放,mm_rb字段为这颗红黑树的根。红黑树可以让内核根据给定的虚拟地址快速地找到内存区域。当我们读取文件/proc/pid_of_process/maps,内核仅仅是通过进程VMA的链接同时打印出每一个。
计算机组成
计算机的运行简单理解为这三层:硬件即组成计算机的所有摸得见看得着的东西是计算机运行的基础;应用程序即完成特定功能、目的的用户程序是计算机的价值体现;中间就是操作系统,连接了硬件和应用程序负责硬件调度、资源管理和分配(内存、文件、CPU等等)、安全等一系列功能。
硬件层
主要硬件包括CPU(算术、逻辑单元)、主存、辅助存储、系统总线、I/O设备(即输入输出)。
CPU:
CPU本身(Processor)可以是单核、多核、多CPU架构,主要目的就是满足日益增长的运算需求。单核比较简单,多核(包括一CPU多核心和多CPU)立即涉及到核心之间高速缓存的共享,此处是CPU内置高速缓存非主存,进程之间寄存器数据的共享和进程处理器调度问题。
总线:
总线连接了所有的设备提供通讯的能力,注意设备之间同一时间的通信是会冲突的,这就要涉及到总线的决策,负责决策的可能是CPU或专有芯片。所有设备需要通信时要提交通信请求有CPU决定下一个通信的设备。
另外一个问题显然连接到总线上的设备越多,冲突的几率就越大效率越差。所以总线可以有多层总线设计,比如设置I/O总线所有的I/O设备都通过I/O总线和I/O控制器连接,I/O控制器则连接在系统总线上代理I/O的通信请求。
速度:
CPU飞快,其中CPU内置的一级高速缓存保持了和CPU同样的速度但是容量极小,接下来可能存在二级、三级高速缓存;主存(内存)其次和CPU存在数量级上的差距;辅寸(多硬盘)的速度就不是一般的慢了,因为有机械运动,但是容量大很多;I/O设备多数慢的要死,但不是没有快的(比如图形、千兆以太网的速度是超过硬盘的)。总而言之就是快的太贵,贱的太慢,访问快的断电数据即失效,不失效的访问慢,所以就有了多级存储的设计。程序的运行必然是加载到主存的(内存)!
局部性:
多级存储的设计得益于局限性能够大幅提升性能。局限性本身分为时间局限性和空间局限性。时间局限性是说现在用到的指令很可能短时间内还会多次调用,空间局限性是现在调用的数据在辅寸上邻接的块很可能即将被用到。就是因为局限性的存在预读取才有了市场(所以有了磁盘整理),当然局限性是必然的——程序肯定趋向于统一存取、循环、分支逻辑肯定是指令的循环调用。——好的命中率决定了计算机的性能。
指令周期(取指周期):
计算机中CPU始终是取指-》执行的动作循环运行的,计算机从取指到完成指令的周期称为取指周期。因此针对CPU的性能优化有流水线和超标量体系结构,前者目的在于合理分割指令使取指和执行能够并行进行(预取指),后者则通过相同的运算结构重复设置实现多条指令同时执行(得益于指令的乱序执行)。
I/O设备进化:
I/O设备一般较慢,极端点的比如键盘这货简直慢的没法说。那么当程序需要读取I/O数据时(如读取一块数据、监听键盘输入)就会被I/O设备阻塞,这是最差的情况整个系统空转直到I/O设备读取数据完成。
于是有了可编程I/O设备——你可以定期问我准备好数据了没,好了你就取没好你就干别的去,也就是轮询这法子还是非常慢因为CPU要定期过来问而且多数情况都是没准备好空耗系统资源(进程切换)。
再后来有了中断,前提是指令的运行是可被中断和恢复的(现在当然都可以,把寄存器数据保存到缓存,完了再恢复嘛),需要读取的时候CPU发给I/O指令然后不理它了,需要读取的进程(或线程)进入阻塞状态换下一个进程来执行,当I/O准备好数据后发送一个中断信号给CPU,这时现在执行的进程被中断CPU会执行一段中断处理程序(通常很短)把之前阻塞的进程标记为Ready(可执行)状态,处理完中断后恢复之前中断的进程(或线程)继续执行。在当前进程执行完或者超时中断后(分时多道程序处理,超时也是一种中断),之前从阻塞中恢复的进程可能会被执行(取决于进程调度,不一定是下一个时间片里也可能是下几个时间片后或者干脆饿死了)。
再后来又有了DMA(直接存储器访问),主要原因就是CPU很忙,你一个拷贝/传输整块数据的动作就不要每块数据都让我来处理了,系统中多了一个专门的辅助芯片干这个事情。CPU下达指令后辅助芯片负责设备之间的数据直接传输。DMA模块可以是总线中的一个模块也可以是I/O模块,但是仍然要占用总线(传输数据)所以并不是不会对系统性能产生影响,至少DMA冲突时CPU要等待一个总线周期。
操作系统
看完硬件层(简单看看,后面可能还要回头),再来看看操作系统层。最基本的元素肯定要包括进程、线程等等用于程序的执行。
操作系统
操作系统目的:
方便:简化了计算机的使用,无论是用户还是开发者角度都极大的简化了对计算机的使用。用户角度提供了交互的能力,开发者角度提供了底层设备的接口、公共库等等。
有效:提高计算机的利用效率。对于操作系统CPU运算、内存、辅存、I/O等等都是资源,如何能最大的利用资源是计算机要考虑的事情。(没有操作系统的年代显然效率非常低,同一时间只运行一个程序计算资源多数时间都在等待I/O设备、人等)。
扩展的能力:在不阻碍服务前提下开发、测试、加入新的计算机能力。比如安装个程序、加个设备。
操作系统发展
串行处理:这是个久远的年代(上世纪50年代也不算太远哈),计算机一次只能运行一个程序,要通过输入设备读入程序(读卡器吧)运行结束后再将结果输出到打印机。这个年代是没有操作系统的。
简单批处理:这个算是操作系统的鼻祖吧?就是常驻内存的一个监控程序,要运行的程序被管理员组织成一批,监控程序从存储器(卡片或磁带)读取要执行的Job将处理器控制权转交给程序运行结束后(成功或失败)控制权返回监控程序继续读入下一个任务。
简单批处理节约了计算机调度和准备的时间——任务不再是一个一个的处理了,变成一批了。
多道程序批处理:现代操作系统进程切换之父?哈哈。由于内存的加大除了容纳操作系统、一个程序以外还有足够的空间容纳第二、第三个程序,所以就有了同时运行多个程序的能力。在第一个程序被阻塞后(I/O等),可以转交控制权个第二、第三个程序。
多道程序批处理节约了CPU等待I/O等慢速设备的时间,这个效率的提升非常客观。
分时操作系统:注意关注在人的交互上。人肯定是比I/O还慢的设备了,由于早年计算机资源的稀缺当然要达到多人共用一台机器的目的。分时操作系统把计算机资源做时间切片,用户通过终端连接到计算机,每个中断都获取到时间切片内的计算资源,由于人是反应很钝的,所以就像没人都有一台计算机服务一样。
操作系统的几张表
Memory table:记录内存的使用情况,回收和分配内存时这里都会被更新。
I/O table:记录I/O设备和通道的情况。
File table:文件系统的占用情况,文件是否存在,文件状态。
Process table:管理进程。
进程和线程
进程
进程包括程序代码和一组(set)数据,是程序运行的实体(应该能算作最小单元吧,线程能执行的是一段逻辑,一个程序的启动至少是一个或多个进程)。
进程的组成:
进程所有属性的集合被称为进程映像(Process Image),这之中一共包括四部分:用户程序(User Program)、数据(User Data)、栈(Stack)和进程控制块(Process Control Block)。
用户程序:要执行的程序。
数据:用户空间中可以被用户修改的部分。比如进程数据、可修改程序。
Stack:每个进程都有一个或者多个栈用于保存参数、过程调用地址、系统调用地址。
进程控制块:操作系统控制进程需要的数据。包含了进程的属性,最基本的每个进程总要有个Id吧,还有进程状态、当前寄存器的值、程序计数器、Stack的指针等等。
进程状态切换
最起码的两个状态:Ready、Running,进程自创建后进入Ready状态也就是可以执行的,这时的进程进入等待队列知道进程调度轮到自己执行时才能够被分配资源进入执行状体Running。
进程的基本状态一共五个,包括上面两个以外还会有被阻塞的情况(I/O、等待生产者生产、信号量等等)所以存在Blocked状态,进程创建过程中存在New状态、进程运行终结后处于Exit状态等待操作系统做进一步处理并销毁进程。
进程状态之间的切换可以参考图中进程状态部分,大体过程:进程被允许创建进入New状态,这个过程中要分配进程Id、划分内存区域、初始化PCB(Process control block)、连接和创建或扩展其它的数据;上述过程完成以后进程可以运行了所以进入Ready状态等待系统调度;终于等到自己运行了,进程为Running状态这时候可能出现几种情况。1,进程运行结束进入Exit状态等待销毁。2,进程运行超时重新进入Ready状态等待下一次调度。3,进程被阻塞了进入Block状态等待所需要的数据或信号准备好,重新唤醒进入Ready状态。除此以外还有两个挂起状态,见下面的切换。
调度的示意图参考进程调度示意子图,其中一个改进是操作系统很可能为不同的中断事件设立不同的阻塞队列,以便提高效率。
进程切换(Swapping):
说白了还是CPU计算资源宝贵和内存有限(内存在涨吃内存的程序也在涨)。为了能让更多的进程可以同时执行(实际上不是同时是调度),程序运行中有很大一部分会被I/O阻塞——原因是I/O太慢了,所以即便你要的数据不多那这个取数的过程CPU也够跑很多其它程序的了。所以导致的问题就是在内存中的进程都阻塞了,内存没地方了,CPU依然闲的蛋疼,怎么办?把硬盘上画出一块地儿(个人理解就是windows下的虚拟内存、Linux中的swap),塞得比较久的那些进程你们先出去待会,换些后面排着的进来。
看到进程切换的子图中除了五个状态以外还有两个挂起态(就绪/挂起、阻塞/挂起)就是这个情况。虽然把进程从硬盘换入换出这个开销非常高,但是硬盘比起I/O设备还是快了很多,所以这一步是有价值的。
当然还有一个路子是虚拟内存的时候,这个稍晚的时候再扯进来。
进程执行模式:
用户模式和内核模式,这两个模式还有多个别名不记录了。这是出于操作系统安全考虑的,有些重要的指令就只有内核模式下才能被CPU执行(硬件支持),总不能任意来个程序什么事情都给他干吧。
有了执行模式就算有模式的切换,比如进程要调用系统操作时(system call)就有可能从用户模式切换到内核模式,system call执行后也会在切换回去。
多线程定义
多线程是指进程内支持并发路径执行的能力。
与进程的关系
一个进程至少包含一个线程,当进程中存在多个线程的时各个线程可以共享进程内的资源。进程内的线程共享进程的用户空间,操作系统仍然通过进程控制块控制进程进而影响到线程。线程本事具备自己的线程控制块、用户栈和系统栈。
创建方式
由于线程类型的不同(下面介绍)线程可以是操作系统创建的也可以使通过线程库(Lib)由进程自己创建的,对于进程创建的线程操作系统是不知道的。
线程优势
l 创建时间开销远小于进程的创建。因为不需要分配用户空间和那么多初始化动作。
l 销毁线程的成本也远低于进程。
l 线程之间的切换消耗低于进程,特别是同一进程内的线程切换消耗更低。
l 线程间通信的效率比进程间通信要高,因为进城之间安全性问题需要隔离和互斥,同一进程内的线程可以共享进程资源而不需要提前获取锁。
线程同步
进程也涉及到同步,但是线程的同步更需要开发者注意。上面提到了线程共享进程的资源并且不需要获取锁,所以线程之间是没有操作系统来保证隔离的。
线程类型
类型分为用户级线程和内核级线程。用户级线程即通过Lib创建的对操作系统是透明的,内核级线程是由操作系统创建的。
用户级
内核级
通过线程库创建,对操作系统不可见
由操作系统来管理
比内核级的线程更高效,不涉及模式切换
在线程切换时需要模式切换(因为是调用系统级的指令)
进程中同时只能有一个线程在运行,还是多段程序的思路
线程可以并发运行,特别指多核计算机
一旦被阻塞整个进程就被阻塞,也就是所有的线程都完蛋了
只会阻塞引起阻塞的线程
线程的四个应用场景
l 前后台运算:即有UI和后台运算的程序,你总不希望后台数据运算时前面的UI界面就对用户没响应了吧?所以这里应该分开线程,后台启动单独的线程运算,界面在不同的线程了所有能时时相应用户的操作(哪怕只是提示计算中)。
l 异步计算:比如应对电路故障的实时备份功能,通过线程无论是在代码量上还是开销上都要比你编写定时调度的功能要高效。
l 速度敏感的运算:多线程的计算机可以在计算一组数据的同时读入下一组数据(当然弄几个进程干这事儿也可以,但是开销明显更大)。
l 模块化的程序架构:对于包含多个活动或者多个源头和目标的输入输出程序,也许更容易使用多线程来设计和实现(就是每个线程干一摊子事儿,大家数据在一起自己取谁也别干涉谁)。
l 另外的比如Java程序,每个程序就是一个JVM的进程,至于这里面你起多少线程操作系统是不关心的。
并发性
竞争条件
竞争条件发生在多进程或者多线程同时修改同一个数据项的情况下,这时数据的最终结果依赖于各个进程(线程)执行的顺序(也就是结果不是唯一确定的了,比如同时修改变量b,P1执行b = 1, P2执行b = 2结果有竞争失败者决定)。
临界区
类似于b的这种资源称为临界资源(critical resource),程序中操作临界资源的程序段称为临界区(critical section)。就是说事儿肯定是出在临界区里的。
互斥(multual exclusion)
多个进程尝试进入同一个不可共享的资源的时候进程间需要是互斥的。这个不可共享的资源就是上面说的临界资源,进入的程序段即临界区。
互斥的要求:
l 互斥是系统强制的。
l 在临界区外挂起的进程不能够干涉其他进程。
l 请求临界资源的进程不能被无限期的延迟,即不能有死锁。
l 当没有进程处于临界区时,对临界资源的请求必须立即分配。
l 互斥不能建立在任何关于进程相对速度或执行顺序的假设上。
l 一个进程在临界区的时间应该是有限的。
进程交互
进程交互分三种情况:
l 进程间互不相认:比如多道程序设计,这些进程间存在共享资源但是彼此不知道,操作系统需要保证进程间的安全。
l 进程间简介知道彼此:进程不知道彼此的ID,但是知道存在共享资源,进程间表现为合作。
l 进程间直接知道彼此:进程知道彼此的ID,存在共享资源,进程间表现为合作。
并发性的硬件支持
Interrupt disable
进程声明自己的某一段程序是不可被中断的,这招只在单个处理器的情况下有用,因为多个处理器则存在进程并行运行。
Compare & swap instruction
由CPU提供的原子指令,用测试值(test value)检查内存单元(*word),如果相等就用给定的值设置内存单元(newvalue),最终返回替换前的内存单元值。
使用:内存单元的初始值是0,多个进程执行用0去测试并替换为1的指令,只有获取到0的返回值的进程获得了进入临界区的资格,在离开临界区前进程要重置内存单元值为0。
Exchange Instruction
有CPU提供的原子指令,用内存区域的值和一个寄存器的值交换。也就是只有换到寄存器初始值(换完以后检查内存区域的值)的那个进程可以进入临界区并在离开时重置寄存器。
硬件支持存在的弊端:
1,采用的是忙等待(busy waiting)的方式,CPU一直在进程间切换,效率低。
2,可能发生饥饿:总有一个二活人品差,抢不到而又没有任何办法干预。
3,可能存在死锁:P1获得了临界资源但是同时P1被P2中断了(P2优先级高),P2却无法获得被P1占有的临界资源,P1同时得不到CPU的计算周期。
并发性的软件支持
信号量(semaphore)
用于进程间传递信号的一个整数值。提供了三种操作初始化、信号加和信号减。只有0和1的信号量称为二元信号量。减操作semwait用于阻塞一个进程(当信号量为0的时候阻塞),加操作semsignal用于激活被阻塞的进程。、
生产者与消费者
生产者负责生产资源并加入到指定的缓存中,加入过程如果缓存已满要阻塞生产者;消费者负责消费资源,如果缓存已空要避免消费者消费不存在的资源。
const int bufferSize = n1;
semaphore s = 1, n = 0, e = bufferSize;
producer
{
while(true)
{
produce();
semwait(e);
semwait(s);//s信号量用于控制每次只有一个进入critical section
append();
semsignal(s);
semsignal(n);
}
}
consumer
{
while(true)
{
semwait(n);
semwait(s);
taken();
semsignal(s);
semsignal(e);
consume();
}
}
监听者(管程)
信号量的麻烦在于分布在程序的各个地方,一处错误就可能导致并发同步的错误。监听者提供了更完善的机制用于并发同步。参考监听者子图。
监听者包括局部数据、条件变量和若干过程和等待队列等,局部变量是被监听者机制保存的处于外部进程不能访问或影响局部变量。
进程可以通过调用监听者的某一过程来进入监听者,但是同一时间只有一个进程处于监听者中(其它的在外面排队,也就是进入队列)。
监听者包含若干个条件变量,可以视条件变量为指向某一等待队列的指针。
监听者提供了cwait和csignal方法,调用cwait(c)将在条件变量c上阻塞当前进程并使监听者可用,当前进程加入到条件变量c的等待队列,调用csignal(c)将激活条件变量c的等待队列上的进程并重新尝试获得监听者(一般是激活一个,也有可能是signalAll<对于条件变量不明确的情况激活所有的进程,使正确的进程运行其它的进程则因为未获得条件变量再次阻塞>)。
除此监听者还提供了紧急队列(也可能没有),对于进入到过程中的但最后没有调用csignal的进程(它可能是在过程中阻塞了或者怎么完蛋了)有两种处理方式:1,踢出去重新回到进入队列和大家竞争。2,考虑到这个进程已经执行了过程的部分逻辑有必要把它加入到紧急队列中,监听者会在空闲后重新激活紧急队列中的进程。
注意与信号量不同的是,在调用csignal(c)的时候如果条件变量c的等待队列上没有任何进程,那这个动作将不产生任何效果也不会累计下去。
生产者/消费者问题中Monitor的实现:
monitor
{
int size, nextin, nextout
appand(node)
{
if(nextin == size) cwait(notFull);
buffer[nextin] = node;
nextin = (nextin + 1) % size;
count++;
csignal(notEmpty);
}
take(char x)
{
if(count == 0)cwait(notEmpty);
x = buffer[nextout];
nextout = (next + 1) % size;
count--;
csignal(notFull);
}
}
消息传递
消息传递是进程间通信的另一个手段,其一个优点是除了进程间还可以适应分布式、共享的系统。消息传递最典型的两个原语:send(source, message)和receive(destination, message),其中可以是阻塞send、阻塞receive的也可以是不阻塞send阻塞receive的或者两者都不阻塞。
消息的组成包括消息头和消息体,消息头包括目的地Id、消息格式、源Id、消息长度等信息,消息体则是消息内容。
寻址:消息可以是一对一的也可以是一对多、多对一或者多对多。
消息的排队原则:默认情况下消息的接收应该是先进先出的对了,除此还要考虑紧急程度的优先级设置。
生产者消费者的消息实现:
producer
{
while(true)
{
receive(mayproduce, pmsg);
pmsg = produce();
send(mayconsume, pmsg);
}
}
consumer
{
while(true)
{
receive(mayconsume, pmsg);
pmsg = consume();
send(mayproduce, pmsg);
}
}
main()
{
create_messagebox(mayconsume);
create_messagebox(mayproduce);
for(int i = 0; i < N; i++) send(mayproduce, null);
parbegin(producer, consumer);
}
读者和写者问题
读者/写者问题不同于生产者消费者,一个资源可以同时有多个读者但是同一时间只能有一个写者。写者和读者不能同时获取资源。
可以存在两种类型的锁
1,读者优先:文件未被占用或存在读者时可以继续加入读者。
2,写者优先:文件被读者占用后一旦出现写者后续不能加入读者。
可以基于信号量或者消息发送来解决,个人觉得能通过信号量的一定能通过Monitor解决。
死锁和饥饿
死锁:两个或多个进程间都需要几个临界资源,但是各个进程持有其中一个临界资源而尝试获取另外的临界资源。
饥饿:可能是优先级或者调度算法本身的原因导致某个进程始终无法获取到临界资源(竞争激烈),虽然不存在死锁但是这个进程做不了任何事情。
联合进程图(Join Process Diagram)
资源类型
可重用资源:比如I/O设备、文件等等,它们在同一时间只可以被一个进程使用,但是使用之后并不会因此而销毁。
可消耗资源:比如存在I/O中的一段流数据,一旦被使用就不在存在了,但是可以被制造出来。除此以外还有信号、中断、消息等等。
死锁形成的条件
1.互斥
2.不存在抢占
3.持有和等待
4.形成了等待的环路
1~3:有可能产生死锁但是并没死锁。只有4发生的时候死锁才是真的产生了。
死锁预防(protection)
死锁的预防不同于死锁避免,死锁预防的目的在于干涉死锁形成的条件1~4使得死锁无法形成,往往导致的成本很高并且不很实用。
1.互斥:无法消除,有并发就有互斥。
2.抢占:这个可以做到有几种途径:a,当进程资源请求被拒绝时强制其释放已占有的资源,在后续需要时可以重新申请。b,当进程申请已被其它进程占有的资源时系统允许其抢占。这两种方法都有一个大前提就是资源状态必须是容易保存和恢复的,否则就啥都没了。
3.持有和等待:可以让进程一次申请所有需要的资源,这将不会出现持有并等待的情况。但是这是在进程能够预测它所使用的所有资源的前提下才成立的,并且效率很低。进程会在没有用到资源前先占用资源。
4.形成环路:可以将各个资源类型定义成线性顺序,只有占有了前面资源的进程才能进一步申请后续资源——同样效率是硬伤。
死锁避免(avoidance)
死锁的避免是运行时发现进程的启动或者请求会导致死锁,从而采取不启动或阻塞的措施。
1,如果进程的请求导致死锁,则不启动进程。这个比较难做到,因为它要求进程提前预知自己要用到的所有资源。
2,如果进程请求的资源可能导致死锁,则不分配资源给进程(塞你一会儿)。这个是更可行的办法。
方法2的运算如下:
OS中始终维护下列数据:
1,矩阵C(claim)为各个进程声明的需要用到资源。
2,矩阵A(allocation)现在以分配给各个进程的情况。
3,向量R当前系统拥有的资源
当一个进程申请起源是,OS假设分配资源给它并更下上面的数据,之后查看是否会产生死锁:
1,C - A得到矩阵P描述每个进程顺利完成时要得到的剩余资源。
2,向量R - A中各个资源的合计值等到向量V当前可用的资源。
3,如果向量V中的资源不足以使P中任何一个进程得到满足,那么即将发生死锁,这时候拒绝进程的请求。
4,如果存在可完成的进程,把进程的资源加入到向量V中重复3步骤直到所有进程可完成或出现死锁。
R1
R2
R3
P1
3
2
2
P2
6
1
3
P3
3
1
4
P4
4
2
2
矩阵C
R1
R2
R3
P1
1
P2
6
1
2
P3
2
1
1
P4
2
矩阵A
R1
R2
R3
P1
2
2
2
P2
1
P3
1
3
P4
4
2
矩阵C - A
R1
R2
R3
9
3
6
系统资源向量R
R1
R2
R3
1
1
当前可用资源向量V
由于当前可用资源可以满足P2,所以可以加回P2的资源并重复步骤3。
死锁的检测和恢复
死锁的检测其实和上面的步骤是一样的需要两个矩阵:Q——进程请求资源(是排除已分配资源后)、A——进程已经分配的资源,一个向量V当前可用资源。
1,标记A中所有资源占用都为0的进程行。
2,初始化临时的向量W是它等于V。
3,查找Q中为标记的i行,其中i行小于向量W。如果找不到i则种植算法。
4,如果找到i行,将i标记并把A中i行数据加回到W中。重复步骤3。
当算法结束时如果存在为标记的行则已经发生死锁。
死锁的恢复有点野蛮:
1,取消所有死锁的进程。这是现代操作系统最常用的办法。
2,回滚进程到之前一个检查点(checkpoint),重新启动。操作系统需要具备回滚和恢复的能力,这样仍然有死锁的风险,但是并发的不确定性能保证死锁最终不再发生。
3,连续取消死锁进程直到最终不再出现死锁。取消进程的顺序依赖某种成本的原则,取消后重新调用死锁检测,如果仍然存在死锁继续取消。
4,连续抢占资源直到死锁不再发生。同样基于某些成本选择的方法,资源抢占后重新调用死锁检测,一个被抢占资源的进程需要回滚到获取该资源前的检查点。
3、4步骤可以考虑一下原则:
l 目前消耗处理器时间最少。
l 目前为止产生的输出最少
l 预计剩下的时间最长。
l 目前位置分配的资源总量最少。
l 优先级最低。
哲学家就餐问题
一个屋子里有5个哲学家他们一天中除了睡觉只做思考和吃饭两件事情,屋子里有一个桌子提供了哲学家喜欢的意大利粉,但是由于哲学家每天至思考导致身体退化他们需要用两个叉子才能够进食,他们坐下后会先拿起左手的叉子,然后拿起右手的叉子,之后进食吃饱以后放下两把叉子。桌子周围一共提供了五把椅子在每个椅子间提供了一把叉子,请为哲学家设计吃饭的算法。
如果5个哲学家同时饿了那么每个人都会拿到左手的叉子而死锁。
哲学家吃饭问题可以通过信号量或者Monitor来处理。
内存管理
内存管理的目的:
l 重定位
l 保护
l 共享
l 逻辑组织
l 物理组织
内存分区
固定分区
分为大小相等和大小不等的固定分区策略。内存预先被划分为固定大小的内存区域,进程可以安装到大于等于自身的内存区域中。
存在内部碎片、大于最大内存区域的进程无法加载、内存利用不充分。
动态分区
动态的根据进程大小进行内存区域划分,从而使得每个进程可以装进和自己大小相等的内存区域。
存在外部碎片、需要定时压缩外部碎片否则内存被割裂成很多小区域。
伙伴系统
采用二分法把内存等大小的两块区域(2^1),再将其中一块区域继续二分为2^2层,逐次分配下去直到进程所需的大小M在2^(N+1) < M <2^(N)时保存进程。在进程释放后再进行合并为较大的块。
伙伴系统弥补了固定分区和动态分区的缺点,但是分页和分段提供了更高级的分区方式。
重定位
因为进程换入换出后不一定仍加载到原来的内存位置,所以在程序中不可能确切的写出实际的内存地址,而是通过偏移量来描述位置。
分页
内存被划分成许多等大小的帧,程序被划分成与帧大小相等的若干页。进程加载时需要将所有页加载到内存中不一定连续的帧中。系统维护了页表描述程序占用的页和空闲页表。
分页没有外部碎片,由于每个帧很小只有最后一帧是可能存在内部碎片的,所以只会出现很小的内部碎片。
页的大小将直接影响性能。页太小时:页数多开始时页面错误率很高,一段时间后由于页面都已加入趋于平稳,但是过小的页将使每次读写的区块很小。页增大时:每一页所包含的单元和相关单元越来越远,局部性被削弱错误率增加,不断增大时错误率又减小当页大小等于进程P时不再有也错误,整个进程都在内存中。由此导致的问题是主存中能存入的进程越来越少。
页表
操作系统为每个进程维护一个页表描述进程中页与帧的对应,逻辑地址分为了页号和偏移量两部分。一般情况下页表的大小位页的大小,页表中每条记录称为页表实体(PTE,page table entry)。
页表可以是多级页表,受制于页大小的限制页表的大小不能大于一页(也不可能把巨大的页表存放在主存中),因此页表做多级处理,根页表始终在主存中,当次级页表不在主存中时从辅存加载对应的页表进主存。
根据页表寻址
l 根据虚拟地址的页号查找根页表对应的帧号。
l 帧号+次级页号合成次级页表的地址找到对应的主存中帧号(如果存在的话)。
l 帧号+偏移量获得实地址。
l 如果页表中页表实体的标志位标志当前页没有加载到主存中,发生页错误中断交给操作系统加载,进程被中断处于Block状态。
反向页表(Inverter Page Table)
这是另一个可行的从虚地址获取实地址的方案。
针对虚拟内存中页表大小和虚拟地址范围成比例的缺点(太大了),反向页表大小是固定的取决于主存中实际帧数。反响列表对虚拟地址的页号做Hash运算取得Hash值,每一个Hash值对应一个数据项。数据项中记录了进程ID和主存中帧号,通过帧号和偏移量就可以得到实地址了。由于多个虚拟地址可能映射到同一个Hash值,反向页表需要维持链结构(当前项连接到同值的其它项),所以进程ID和Hash值共同决定了虚拟地址对应的数据项。
反响的含义是指使用帧号而不是页号来索引页表项。
转移后备缓冲器(TLB,Translation Lookside Buffer)
这是(虚拟内存地址转换)硬件设备的一部分,相当于高速缓存。因为正常情况下虚拟地址的访问要经过两次主存——一次查找帧地址,一次取数据,转移后备缓冲器缓存了页号和帧地址的对应关系,只有在未命中的情况下采取访问页表查找帧号。
分段
简单分段类似于简单分页,是将主存换分成大小不等的若干段,一个进程可以存储在不连续的段中。分段的大小受限于分段最大长度。分段对程序员是可见的,它具有处理不断增长的数据结构的能力以及支持共享和保护的能力。操作系统为每个进程维护一个段表。
分段存在外部碎片。
段页结合
段页结构是将程序划分成段,每段保存在主存中对应的段里,在主存中段是由等大小的多个页组成,当段最后不足一个页时占用一个页。
段页结合的方式结合了分段和分页的长处。在分段系统中由于每段有长度属性,避免了程序不经意的越界访问。进程间存在共享时多个进程可能持有同一个段的引用,页结构也可以是实现类似的结构。
虚拟内存
当程序太大超过主存时就需要虚拟内存了,另外多道程序设计希望同时有尽可能多的进程加载到内存中,由于局部性的原理进程不需要全部加载进内存而是加载频繁是用的区块(称为驻留集),进程的其它部分保存着专门的辅存区域中。这个机制称为虚拟内存。
系统抖动
当系统换出一块内存区域后紧接着它有需要调用它,当这种情况频繁发生的时候就导致了系统抖动。
读取策略
分为请求式分页和预约式分页。请求式分页是指当确实需要访问到某页时才把它加载进主存,预约式分页是利用局部性原理将可能访问到的当前请求的后续页面加载到主存中。显然预约式分页更可取,但是会造成一定的浪费,在首次加载页面和发生页错误时适合采取预约式分页。
放置策略
替换策略
替换策略是在加载新的页时主存已满需要替换出页时决定那些页将被替换的算法。
最佳(OPT,Optimal)
最少发生页错误的算法,是优先替换那些距离访问最远的页面,需要预知页的请求顺序,本身是不可能实现的,但是可以作为参考比对其它策略。
最近最少使用
实际上是性能上最接近最佳的,但是仍难以实现。一种实现方式是给每个页定义最近访问的时间标签,并在每次访问后更新标签,即使通过硬件支持成本和开销仍然很高。
先进先出
依赖的理论是一个在很久以前加载的页现在很可能已经不再访问了,但是结果往往并非如此,这种策略很容易实现。
时钟
环形的结构,通过指针指示当前所在位置,每个页有一个使用为在访问后标记其值为1。在需要替换时移动指针找到第一个标记位等于0的页,指针每移动过一个页就将这个页的使用位清零。这样如果没有使用位为0的页,当移动一圈以后最初的位置就会被清理。
一个改进是增加修改位——这也是必须的因为被修改的内存必然要写入辅存。现在有两个指示位(访问u,修改m),算法如下:
1,查找u=0,m=0的页,如果存在替换。这一步不清零访问位。
2,如果1失败,查找u=0,m=1的页,并且这个过程中把访问位清零。
3,如果2失败,重复1,必要时重复2。
这样好处是尽量不去替换发生数据修改的页,少了写回辅存的动作。
页缓冲
也是避免系统抖动的一个策略,在主存中划分出一定的缓存,用于保存那些被替换出的页,根据局部性原理他们很可能近期会被访问到。这个缓存是一个先入先出的队列,一般页面被访问则直接从缓存中取回,如果一直没有被访问则最终会被挤出缓存。
驻留集管理(Resident Set)
虚拟内存中并非一个进程的所有部分都加载到主存中,程序运行过程中常驻内存的部分称为驻留集。
驻留集的讨论包括两部分:驻留集分配(大小)和替换范围。其中驻留集不可变的情况下替换算法已经在替换侧路讨论过了,驻留集可变的情况下将有所不同。
固定分配,局部范围:每个进程的驻留集大小固定,每个进程一旦有一个页换进来就要有一个页换出去。需要根据程序的类型、优先级等预先分配固定的大小,一旦过小则会保持较高的也错误率,如果较大则会占用资源,系统运行缓慢。
动态分配,全局范围:根据进程运行的状态调整驻留集的大小,如果页错误率较高就适当加大驻留集,如果进程错误率一直保持较低水平说明程序的驻留集足够大,可以适当削减一些也不会危及程序。全局范围则可在所有进程间选择要被替换出的页,难点在于没办法确定该从哪里换出页(即很可能换了不该换的),解决办法是页缓冲。
动态分配,局部范围:动态分配的效果同上,同时限制在进程自己的范围内换出页。在这个策略中要求对增加或减少驻留集大小进行评估并且要预估将来进程的情况,因此比简单全局替换要复杂得多,但会提供更好的性能。
驻留集的替换策略
工作集策略(Working Set)
W(t,r)是关于t和r的函数,t是单位时间,r是窗口的宽度定义最近的r个单位时间中用到的页的集合。即始终有W(t, r+1) 包含 W(t, r)。
工作集如下工作:
1,监视每个进程的工作集。
2,周期性的从一个进程的驻留集中移除那些不在工作集中的页,可以使用LRU策略。
3,只有当一个进程的工作集在主存时才可以执行该进程(也就是驻留集包含了工作集)。
首先工作集是有效的,它利用率局部性原理,并未该原理设计了一个可以减少页错误的内存管理策略。遗憾的是工作集存在很多问题:
1,现在不总是代表未来。
2,开销太大,实现监视每个进程不现实。
3,r最优值未知。
但是工作集提供了参考,以下方案都是基于工作集思想的:
页错误频率(Page Fault Frequency,PFF)
主存中每个页都有一个使用位(和时钟的一样作用),操作系统记录每个进程上一次页错误的时间戳,如果发生了页错误查看两次页错误的时间间隔如果小于阈值F,则加入新的页(扩大驻留集),否则清除所有使用位为0的页,并把当前驻留集的页使用位清零(缩小驻留集)。一个改进时加入使用两个阈值——一个是驻留集增加的最高阈值,一个是驻留集减小的最低阈值(指频率)。
页面错误频率是工作集的一个折衷,使用页缓冲则可以达到相当好的效率。但是一个缺点是如果要转移到新的局部性,会导致暂时的驻留集猛增。转移到新的局部性是指,进程运行一段时间会切换到不同的逻辑指令部分,这时候局部性发生偏移,之前的驻留集不再需要。
采样间隔可变工作集(Variable-interval Simple Working Set,VSWS)
针对PFF在内存高峰是来不及淘汰就得驻留集而导致进程频繁换入换出等开销(频率不够快),采用动态的采样率以期望尽快淘汰不需要的页。
采用三个参数:L采样区间最长宽度、M采样区间最短快读、Q采样区间允许发生的页错误数。VSWS和PFF一样使用了页的使用位,不同之处在于频率的调整:
1,如果采样时间超过了最长时间L,挂起进程并扫描使用位。
2,未达到最长时间,但是页错误数超过了Q:
2.1,如果采样间隔超过了M则挂起进程并扫描使用位。
2.2,如果采样间隔没有超过M,则一直等待采样时间到达M进行扫描。
清除策略
清除策略目的在于确定何时讲一个被修改的页写回辅存,分为请求式清除和预约式清除。
请求式清除采取动作的时间比较慢,影响性能。
预约式清除把需要修改的页在需要用到它们的页帧之前批量的写回辅存。但是预约式清除写回的页在替换策略确定移除它之前仍有驻留在主存中,这期间可能再次发生修改导致清除无意义。
改进办法是使用页缓冲,分为两个表存储替换策略淘汰的页。一个表寸修改的页,一个表存未修改的页,修改表中的页被批量的写回辅存,然后移动到未修改表中,未修改的表准备被挤出或者拿回。
加载控制
加载控制是关注多道程序设计的控制,系统中多道程序的数量称为多道程序设计级。当多道程序数量过少时系统会比较空闲,过多时则会导致较高的页错误率和抖动。
一个方案称为L=S,L是页错误间隔的平均时间,S是页错误的平均处理时间,实验表明当两者接近时处理器使用率达到最大。
另一个方案是50%方案,即始终报纸分页设备的使用率保持在50%左右,此时的处理器使用率也是最大。
另外策略是监视时钟(Clock)替换策略的环形缓存区指针移动速度,当移动速度低于某个阈值时可能是以下两种情况之一:
1,很少发生页错误,指针很少移动。
2,未被使用的驻留页太多,指针不需要移动太多就可以找到可清除页。
这两种情况都表明进程的驻留集分配太大,可以增加多道程序设计级。另外还可以包括一个高阈值,如果指针移动速度超过这个阈值,则表明多道程序设计级太高,导致频繁的页错误,则要挂起进程以减少多道程序设计级。挂起进程的策略可以是:
l 最低优先级
l 正在发生页错误的进程(Faulting process):原因是该进程很肯能驻留集还没有形成,因此暂停它的代价很低。
l 最后被激活的进程:同样很可能有最小的驻留集。
l 拥有最小驻留集的进程:重新装入的代价最小,但是不利于驻留集较小的程序。
l 最大的进程:释放较大的空间,不用很快又去取活其它的进程。
l 具有最大剩余执行窗口的进程:类似于最少剩余时间策略,把已运行时间最短的挂起。
处理器调度
单处理器调度
调度类型
长程调度:决定是否将任务加入到待执行的进程池中。
中程调度:决定进程的部分或全部加入到内存中(从Suspended到Ready)。
短程调度:决定哪一个就绪的进程将被执行。
I/O调度:决定哪一个挂起的I/O请求将被可用的I/O设备执行。
处理器调度关注的是短程调度。
调度准则
面向用户
响应时间:从任务提交到开始有响应输出的时间,一般的当处理器开始处理任务时即开始有输出。
周转时间:从任务提交到任务完成的时间。
最后期限:当可以指定最后期限时,操作系统降低其它目标,是满足最后期限的作业数目的百分比达到最高。
可预测性:无论系统当前负载情况是繁重还是空闲,一个给定工作完成的总时间和总代价应该是相等的。
面向系统
吞吐量:单位时间内完成的进程数。
处理器利用率:处理器处于忙状态的时间百分比。对于昂贵的共享系统来说这是一个重要的准则,对于个人系统则显得不那么重要。
公平性:没有来自用户或其它系统的指导时操作系统应该公平的对待所有进程,没有一个进程会处于饥饿状态。
强制优先级:当指定了优先级后调度策略应优先响应高优先级的进程。
平衡资源:调度策略应是系统的所有资源保持忙碌的状态,较少使用紧缺系统资源的进程应该得到照顾。
调度算法
归一化周转时间:它是指进程周转时间与服务时间的比率,最小值是1.0.该值表示进程的相对延迟,典型的进程的执行时间越长可容忍的延迟越长。
先来先服务(FCFS):没有优先级和抢占,所有进程按照加入的顺序执行。这样的调度偏向于执行时间长的进程。FCFS策略本身对操作系统不是很有吸引力,但是它经常和优先级系统配合使用产生有价值的调度策略。
轮转(Round Robin):对处理器资源进行时间分片,依次分配相同的时间资源给每个就绪的进程。轮转的时间片最好略大于一次典型交互的时间,当时间片足够大时退化为FCFS策略。
轮转增加了处理时钟中断、进程切换和分配函数的开销,因此时间片不应该过短。该策略对短执行时间的进程有所改善,但是一个问题是进程分为I/O密集型和处理器密集型,由于I/O密集型进程经常被I/O中断,所以轮转策略倾向于处理器密集型。
一个改善的策略是虚拟轮转法(Virtual Round Robin),它增加了一个I/O队列,当一个进程被I/O阻塞后它加入到I/O队列,在就绪后它I/O队列有高于就绪队列的优先级,该进程后续的执行时间与已执行时间的和不会超过时间片。
最短进程优先(SPN,shortest process Next):具有最短执行时间的进程有更高的优先级,它依赖于系统估计进程的执行时间,在批处理系统中任务加入时程序员给出任务的估计时间,如果任务执行时间远远超过给出的估计时间它将被废弃。在生产环境中有大量的重复任务,系统将监控每次任务执行的时间以估计执行时间,最简单的公式是s=(各次时间和)/n,一个避免每次求和的优化是s=S(n-1) + Tn/n,上述公式每次执行的权值是相同的,典型情况下我们希望最近的执行情况有更大的权值Sn+1 = aTn + (1-a)Sn。
最少剩余时间(SRT,shortest remain time):是SPN的改进版本增加了抢占机制,在不断有短进程加入的情况下长进程可能处于饥饿状态。
最高相应比优先(HRRN,Highest Response Rapid Next):使用公式(w+s)/s,其中w是等待时间,s是服务时间。操作系统始终选择具有最高相应比的进程,同样需要估计和记录进程的服务时间。该策略非常具有吸引力,当偏向短进程时,长进程由于得不到处理响应比不断增加。
反馈:不想SPN、STR、HRRN策略那样需要估计时间,反馈策略倾向于短进程,它具备多个队列Q1~Qn,当进程加入时处于Q1队列中,采用FCFS的顺序服务队列中的每个进程,当进程允许超过时间阈值时中断并加入到下一级队列中Q2,依次类推。Q1具有最高的优先级,只有Q1中不存在进程是才执行下一级的队列。这样可能导致的问题是过长的队列可能加入到Qn队列后处于饥饿状态,因此要见识进程的等待时间,如果超过一定长度则重新调入到Q1中。
多处理器调度
多处理器调度关注的类型
粒度
无约束并行性:进程之间没有显示的同步,每个进程都是一个单独的程序。无约束并行可能达到每个用户都像是使用单独的计算机或工作站。
粗粒度和非常粗粒度并行性:进程之间存在这同步,但是在一个非常粗浅的级别上,这种情况可以简单的处理成一组运行在多道程序单处理器的并发进程,在多处理器系统是允许的软件进行很少或者不进行改动就可以支持。
中等粒度并行性:应用程序可以被进程中一组线程有效的实现,这种情况下程序员需要显示的指定潜在的同步性,应用程序之间需要高程度的合作与交互。
细粒度并行性:代表着比线程间更加复杂的同步情况,迄今为止仍是特殊的未被分割的领域。
进程调度
集中调度or对等调度:
集中调度即调度中存在主处理器,所有的任务分发由主处理器来完成,这种情况下主处理器可能成为系统的瓶颈。
单处理器使用多道程序设计:
与单处理器性能的不同:
多个处理器系统中由于一个长进程在单个处理器上执行时,其它的进程可以分配到另外的处理器上因此复杂的调度策略不再显得非常重要,调度策略的开销可能成为性能损失。FCFS策略变得可接受。
线程调度
负载分配:
提供全局队列,每个处理器只要空闲就从队列中取任务执行。
优点是:负载均匀的分配给处理器,不存在空闲的处理器;不需要集中调度;可以使用单处理的任何一种调度方案进行分配。
缺点是:中心队列占居了必须互斥访问的存储器区域,因此多处理器同时查找时会成为瓶颈,当只有几十个处理器时不是大问题,但是上百个处理器时就会出现瓶颈。被抢占的线程可能在不同的处理器上执行,如果每个处理器都配有高速缓存的话那么命中率将非常低。如果进程的所有线程都视为在公共线程池中那么进程的线程可能不会同时被处理,当线程间存在高度合作时则出现瓶颈。
组调度:
一组相关的线程基于一对一的原则,同时分配到一组处理器上去。
优点:如果紧密相关的进程并行执行那么同步阻塞可能减少,从进程推广到线程组调度把一个进程所有的线程视为相关的;调度开销可能减少,因为进程内线程间可能相关如果一个线程在高速允许,而它以来的线程没有运行就会出现阻塞和调度。
缺点:组调度同一时间调度一个进程中相关线程,某些进程的特性可能至适应单线程允许将会出现其它处理器空闲的情况,解决办法是把若干单线程的进程视为一组允许。
专用处理器分配:
每个程序执行时被分配给一组处理器,处理器个数与进程的线程数相等,当进程执行完后处理器返回到处理器池中等待处理其它任务。这个策略看似是极端浪费的,它会等到进程运行结束才将处理器分配给其它的进程使用,而一旦一个线程被I/O阻塞执行它的处理器将空闲。
采用这个策略的原因:
1,高度并行的系统中有数十或者数百个处理,每个处理器只占系统总代价的一小部分,处理器利用率不再是衡量有效性或性能的重要因素。
2,一个程序的生命周期里避免进程切换会加快程序运行。
动态调度:
执行期间进程的线程数可以改变。某些应用程序可能提供了语言和系统工具允许动态的改变进程中的线程数目。提供了一种操作系统和应用程序共同进行调度决策的方法。
当一个作业请求一个或多个处理器时:
1,如果有空闲处理器分配满足它们需求。
2,否则如果作业新到达,从当前已分配多个处理器的作业中分出一个处理器给它。
3,如果都不满足那么作业处于未完成状态直到有空闲的处理器或者改作业废除它的请求。
4,当释放一个或多个处理器时为这些处理器扫描当前未满足的请求队列,给每个没有分配处理器的作业分配一个处理器,如果还有空闲处理器再次扫描队列,按照FCFS原则分配处理器。
I/O设备调度
I/O功能的逻辑结构
逻辑I/O:逻辑I/O层将I/O设备视为逻辑资源,不关心底层的细节。逻辑I/O代表用户进程管理的一般I/O功能,允许它们根据设备标识符以及诸如打开、关闭、读取等操作与设备打交道。
设备I/O:请求的操作和数据(缓冲的数据、记录等)被转换成适当的I/O指令序列、通道命令和控制器指令。可以使用缓存技术以提高使用率。
调度和控制:关于I/O操作的排队、调度和控制发生在这一层,可以在这一次处理中断,收集和报告I/O状态。这一层是与I/O设备真正打交道的软件层。
I/O缓冲
I/O设备划分:
I/O设备分为面向块(block oriented和面向流(stream oriented)的设备,面向块的设备将信息保存在块中,通常是固定大小的,传输过程中一次传送一块。面向流的设备以字节流的方式传输数据。
单缓冲:系统在发送I/O指令后给I/O设备分配一块位于主存中的缓冲区,传输数据被放在缓冲区中,当传输完成时立即尝试读取下一块。根据局部性原理有理由期望下一块被读取,这种机制称为超前读。
双缓冲:单缓冲时I/O设备必须等待读取缓冲区中数据被完全读出才能再次写入,双缓冲设置两块缓存区域以平滑这种趋势。设C为进程处理块的时间,T位读取块的时间,我们可以粗略估计块的执行时间位max(C,T),当C>=T是进程将不需要等待I/O,当C<T是则I/O设备可以全速运行。
循环缓冲:当爆发性的执行大量的I/O操作时,则仅有双缓冲就不够了,这种情况下使用多于两个缓冲的方案来缓解,这种缓冲区域自身被当成循环区域使用。
需要指出的是缓存是一种技术旨在平缓I/O请求峰值的,当进程需求的I/O平均值大于I/O传输速度是再多的缓冲也不能解决问题。
磁盘调度
磁盘性能参数
寻道时间:机械臂移动到数据所在轨道的时间,现在典型磁盘的寻道时间Ts=10ms。
旋转延迟:磁盘旋转到要读取的数据位置的延迟,一般取平均时间即1/2r,其中r表示转速。
传送时间:磁头读取数据所花费的时间b/(Nr),b表示要读取的字节数,N表示磁道上总字节数,r表示转速。
磁盘调度策略
先进先出
先来的请求先服务,由于数据的请求式随机的,会导致较高的寻址时间,效率差。
优先级
优先级是高优先级的请求先服务,一般是为了满足操作系统的特定目的,并没有改善磁盘性能的能力。
后进先出(LIFO)
令人惊讶的是这种选取最近请求的策略有许多优点。把设备资源提供给最近(使用系统)的用户时会导致磁头臂在一个顺序文件中移动时移动的很少,甚至不移动。利用这种局部性原理可以提高吞吐量减少队列长度,只要一个作业积极的使用磁盘它就能尽快得到处理。
当然如果有大量的请求就会导致最先的请求饿死。
最短服务时间优先(SSTF)
总是选择磁头臂移动最少的请求响应,对于移动距离相等的请求可以随机移动向一边。同样如果一个进程大量的请求临近的数据会导致其它请求饥饿。
SCAN:
SCAN要求磁头臂向一个方向移动,移动过程中响应在当前磁道的请求。当磁头臂到达最外(内)层磁道时,再反向扫描。这种算法并没有很好的利用局部性原理(对最近横跨过的区域不公平,不如SSTF和LIFO好),由于两侧的数据被快速的扫描了两次因此它偏向于外围数据(局部性原理)。
C-SCAN
限定在一个方向扫描,当达到最后一个磁道时,磁头臂返回到相反方向的磁道末端重新开始扫描。
N-step-SCAN和FSCAN
为了克服进程的粘滞性,在SCAN和C-SCAN中一个或多个进程对一个磁道有较高的访问速度时可能会垄断这个磁道一段时间。N-step-SCAN设置若干个N个请求的队列,每次扫描只响应一个队列里的请求,当开始扫描时新的请求需要加入到下一个队列中。
RAID
RAID是一组磁盘系统把它们看为一个单个的逻辑驱动器。
数据分布在物理驱动器阵列中
使用冗余的磁盘容量保存奇偶检验信息,保障一个磁盘失败时,数据具有可恢复性。
磁盘高速缓冲
高速缓存是系统从主存中划分的一块区域,利用了局部性原理保存最近访问的数据块,用于提高更好的磁盘性能。
替换算法
LRU:最少访问,将缓冲区设置为一个栈,当一个块被访问后加入到栈中,如果再次得当访问则把该块从当前位置移动到栈顶,随着块的加入那些不被访问的将会挤出栈中。
LFU:最小频率访问,对缓存中的块增加计数特性,每次被访问到时计数加1。当访问辅存时,把计数最小的块移除,加入最近的块。由于局部性的问题,一个块可能短时间内多次访问使得计次很高,但是这之后并不意味着还会再次访问它,所以LFU并不是一个好的算法。
基于频率的替换算法:克服LFU的确定,在LRU的栈模型中划分出位于栈顶的若干帧为新区,当块位于新区是重复访问不增加访问次数。
文件管理
文件系统软件结构
基本文件系统:计算机与外部环境的接口,该层处理磁盘、磁带的交互数据。
基本I/O管理程序:负责所有文件I/O的初始和终止。
逻辑I/O:是用户和应用程序能够访问到记录。
访问方法层(堆、顺序文件、索引顺序文件、索引、散列):距离用户和应用程序最近的层,在应用程序与保存数据的设备之间提供了标准接口。
文件结构:
域(Field):基本的数据单元,一个域包含一个值,如雇员名字、日期等。
记录(Record):一组相关域的集合,可以看做应用程序的一个单元。
文件(File):一组相关记录的集合,它被用户或应用程序看做一个实体,并可以通过名字访问。
数据库(DB):一组相关数据的集合,它的本质特征是数据之间存在着明确的关系,可供不同的应用程序使用。
文件组织和访问
堆:
最简单的文件系统。数据按它们到达的顺序被组织,通过特定的分隔符或特定的域指明。每个域应该是自描述的,数据之间不一定存在联系或相同的格式。
当数据在处理器采集并存储时或者当数据难以存储时会用到堆。只能穷举搜索,对大多数应用都不适用。
顺序文件:
文件具有固定的格式,所有的记录都有相同的格式,具有相同数目、长度固定的域按照顺序组成。每条记录第一个域称为关键域,唯一标识了这条记录。
交互的表现较差,需要顺序的搜索。一种情况下顺序文件按照顺序存储在磁盘上,在发生文件修改时需要移动数据,可能的处理方式是把数据存在临时堆上,定期的将数据批量写回顺序文件。另一种情况文件可能采用链式存储,该方法带来一些方便,但是是以额外的处理和开销为代价的。
索引顺序文件
弥补了顺序文件检索的问题。检索文件可以是简单的顺序文件,每条记录包括两个值一个关键域和指向文件的指针。简单的检索可以是一级的,也可以由多级检索。查找文件时找到相等的域或者关键域值之前最大的域。
索引文件
顺序文件和索引顺序文件只能是顺序检索或对关键域检索,索引文件对感兴趣的域提供了索引,索引文件本身可以是顺序的。索引文件分为完全索引和部分索引,差别在于被索引的域是全部域还仅仅是感兴趣的域。
索引文件一般只提供索引访问的方式,不再支持顺序访问,因此记录的组织也不必是顺序的,应用程序只能通过指针访问。
直接文件或散列文件
直接文件或散列文件开发直接访问磁盘中任何一个地址一致的块的能力,要求每条记录中都有一个关键域,但这里不存在顺序的概念。
记录组块
磁盘中数据保存在块中,块越大每次传输的数据越多,效率越高。当时大的块要求操作系统提供更大或者复杂的缓存,并且由于局部性的关系大块中的数据可能是应用程序不需要的造成浪费。
固定组块
使用固定长度的记录,并且若干条完整记录保存到一个块中,每个块末尾可能有未使用的空间称为内部碎片。
可变长度跨越式组块
块的长度可变,记录可以跨越块保存,如果一个块的末尾空间不足一条记录时,剩下的数据可以保存在下一个块中,通过后继指针指明。造成了更复杂的处理,并且当读取跨越块的数据时需要读取两次,消除了内部碎片。
可变长度非跨越式组块
和上面相同,但是记录不可以跨越块保存。
二级存储管理
文件分配
预分配:文件请求时声明需要的空间,一次性分配。
动态分配:根据文件的增长每次分配一定的空间,或者一块。
分配方法:
连续分配:始终给文件分配连续的空间。这种分配方式对于顺序文件非常高效,并且可以简单的检索到需要的文件块。但是会产生外部碎片,并且需要实时运行压缩程序以消除外部碎片。
链式分配:文件不需要顺序保存,每块尾部通过指针指向下一块数据,文件分配表中同样只要保存一个表项。
链式分配的一个后果是局部性不再被利用,如果要顺序的读取一个文件时需要一连串访问磁盘的不同部分,这对系统的影响很严重。一些系统周期性的的对文件进行合并。
索引分配:每个文件在文件分配表中有一个一级索引,分配给文件的每个分区在索引中都有一个表项,典型的文件索引在物理上并不保存在文件分配表上,而是保存在独立的一个块上,文件分配表中该文件索引指向这个块。
可以消除外部碎片,按大小可变的分区分配可以提高局部性,任何情况下(大小可变分区、按块保存)都需要不时的对文件进行合并。使用大小可变的分区情况下合并可以减少文件索引。索引分配支持顺序和直接读取数据,是最普遍的一种文件分配形式。
空闲空间管理
位表:使用一个向量,向量的每一位代表一块磁盘,0表示空闲,1表示使用。优点是容易找到一块或一组连续的空间,问题是需要穷举来找到合适大小的区域,当磁盘剩余很少空间时这个问题尤为严重,因此需要设置特殊的数据结构辅助查找。如位表可以在逻辑上划分为不同的区域,建立区域汇总表统计每个区域的使用情况,查找空闲位时可以先找到合适的区域在查找位表中这部分区域的使用情况。
位表需要加载在主存中,一个位表所需要的存储总量为【(磁盘大小)/(8*文件系统块大小)】(计算的是占用的字节数),因此一个16GB的磁盘,块大小位512字节时位表占用4MB,如果每次去数据都从硬盘加载4MB的位表的话这个速度是难以忍受的。
链式空闲区
空闲表可以使用指向每个空闲区的指针和他们的长度值被连接在一起,因为空闲表只需要一个指向第一个空闲区的指针,因此这种情况下空闲表的大小是可以忽略的。
这种分配法适合所有的文件分配方法,如果按块分配可以移动位于头部的指针,如果是按区域分配则可以顺序的找到合适的区域并更新指针。
存在的问题:1,使用一段时间磁盘会出现很多碎片,许多区变成只有一块大小。2,写时需要先读取该块以发现下一块的指针,如果进程请求大量的单个块这个效率是很差的,同意删除的时候也会导致很慢。
索引
索引是把空闲空间看做文件,使用之前介绍的索引表的方式记录。基于效率的原因,索引适合使用在大小可变的分区分配的情况下。
空闲块列表
每个空闲块都有一个顺序号,把顺序号保存在磁盘的一个保留区中。根据磁盘的大小,存储一个块号需要24位或32位。这是一种令人满意的方法,空闲块列表部分保存在主存里:
1,磁盘空闲块列表占用空间小于磁盘空间的1%。
2,尽管空闲块太大了,不能保存在主存。但是两种有效技术把该表的一小部分保存在主存里:
a,这个表可以是一个下推栈,栈中靠前的数千元素保存在内存中,当分配一个新块时它从栈顶弹出,同样当一个块被接触时把它压入栈中。只有栈中部分满了或者空了时候才需要从磁盘传输数据,通常情况下它是零访问时间的。
b,这个表可以看所FIFO的队列,分配时从头部取走,取消分配时从队尾入队,只有队空了或者满了时才需要与磁盘传输。
看了“操作系统总结知识”还想看:
1.操作系统主要知识点
2.操作系统知识大全
3.操作系统基本知识 操作系统知识点
4.linux操作系统基础知识总结
5.系统与设计知识点归纳