目录
1 概述
2 系统调用
3 进程
4 内存管理
5 文件系统
6 I/O
1 概述
1.1 操作系统概念
程序员不会直接和硬件打交道,故在硬件的基础之上,计算机安装了一层软件,这层软件能够通过响应用户输入的指令达到控制硬件的效果,从而满足用户需求,这种软件称之为操作系统 Operating System(OS)。
常见的操作系统有Windows、Linux、FreeBSD或OS X,这种带有图形界面的操作系统统称为图形用户界面(Graphical User Interface, GUI);而基于文本、命令行的通常称为Shell。两者统称为用户接口程序。
1.2 系统中进程的分类
(1)内核态:软件中最基础的部分是操作系统,运行在内核态。
(2)用户态:运行用户接口程序,可以直接读取用户程序的数据。
为了获取操作系统的服务,用户程序必须使用系统调用(System Call),系统调用会转换为内核态并且调用操作系统。
1.3 内核
(1)内核(Kernel)是操作系统的核心部分。它负责系统的内存管理,硬件设备管理,文件系统管理以及应用程序管理。
(2)对比CPU
· CPU(Central Processing Unit)中央处理器
· 组成:控制器+运算器
· 根本任务:执行命令
· Kernel内核
· 连接应用程序和硬件的桥梁
· 决定者操作系统的性能和稳定性
1.4 计算机硬件
(1)计算机组件
(2)存储器
存储器系统采用一种分层次的结构。顶层的存储器速度最快,但容量小,成本高。层级机构越向下,其访问效率越低,容量越大,造价越便宜。
· 主存通常是RAM,是内存系统的主力军。
· 还有一些ROM(不可重复写)用于启动计算机的引导加载模块(bootstrap)。
· 需要注意,固态硬盘(SSD)不是磁盘,固态硬盘并没有可以移动的部分,外形也不像唱片,并且数据是存储在存储器(闪存,一种可重复擦写的存储器,速度介于RAM和磁盘之间)中,与磁盘唯一的相似之处就是它也存储了大量即使在电源关闭也不会丢失的数据。
· 一些地址的转换和管理,由CPU中的存储器管理单元MMU部件完成
· 从一个程序切换到另一个程序的机制称为上下文切换。
(3)计算机启动过程
· BIOS开启。基本输入输出系统(Basic Input Output System, BIOS),有底层IO软件,包括读键盘、写屏幕、磁盘IO以及其他过程,被保存在闪存中,非易失性。它会检测所安装的RAM的数量,键盘和其他基础设备是否已安装并且正常响应。
· BIOS扫描PCIe和PCI总线并找出连在上面的所有设备。
· BIOS通过尝试存储在CMOS存储器中的设备清单尝试启动设备。用户可以在系统启动后进入BIOS配置程序,对设备清单进行修改。
· 判断是否能够从外部CD-ROM和USB驱动程序启动,如果没有外部驱动,则从硬盘启动。
· 将boots设备中的第一个扇区读入内存并执行。该扇区包含一个程序,程序通常在引导扇区末尾检查分区表以确定哪个分区处于活动状态。
· 从分区读入第二个启动加载程序,该加载器从活动分区中读取操作系统并启动它。
· 操作系统询问BIOS获取配置信息。对每个设备来说,会检查是否有设备驱动程序。如果没有,则会向用户询问是否需要插入CD-ROM驱动或者从Internet上下载。
· 有了设备驱动程序,操作系统把它们加载到内核中,然后初始化表,创建所需的后台进程,并启动登录程序或GUI。
1.5 操作系统扩展
除了在计算机初启动时所装载的核心操作系统外,许多操作系统还支持额外的扩展。比如IO设备驱动和文件系统,这些部件可以按需装载。
在UNIX中叫做共享库(shared library);Windows中叫动态链接库(Dynamic Link Library )DLL,扩展名为.dll,在C:\Windows\system32目录下存在1000多个DLL文件。
2 系统调用
2.1 概念
运行用户程序时,凡是与内核态级别的资源有关的操作(若文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。
只有通过系统调用才能进入内核态。
2.2 示例
count = read(fd,buffer,nbytes);
2.3 分类
可移植操作系统接口(POSIX)常用系统调用(UNIX)如下。 pid是系统进程id,fd是文件描述符,n是字节数,position是在文件中的偏移量,seconds是流逝时间。
2.3.1 进程管理
2.3.2 文件管理
2.3.3 目录和文件系统管理
2.3.4 其他
2.4 Windows系统调用
Windows中,函数库的调用和实际的系统调用几乎是不对应的。微软定义了一系列过程,称为Win32应用编程接口(Application Programming Interface),即Win32 API。
3 进程
3.1 进程概念
(1)进程的本质就是操作系统执行的一个程序。
(2)地址空间:进程在其中可以进行读写操作和记录相关的资源级,包括程序计数器、堆栈指针、打开文件的清单等
(3)操作系统中存在一个进程表,是数组或者链表结构,当前存在的每个进程都要占据其中的一项。故一个挂起的进程包括:进程的地址空间和对应的进程表项。
3.2 对比线程
(1)线程是进程的更小运行单位,一个进程可以有多个线程
(2)进程基本上独立,但线程会相互影响
(3)线程开销小,但不利于资源的管理和保护,但进程相反。
3.3 进程生命周期
(1)创建状态(new)
· 进程正在被创建,尚未到就绪状态。
· 创建进程的方式:
· 系统初始化
· 正在运行的程序执行了创建进程的系统调用(fork)
· 用户请求创建一个新进程
· 初始化一个批处理工作
(2)就绪状态(ready)
获得了除CPU时间片外的一切资源
(3)运行(running)
进程在处理器中运行
(4)阻塞(waiting)
进程正在等待某一事件而暂停运行,如等待某资源为可用或等待IO操作完成。即使处理器空闲,进程也不能运行。
(5)终止(terminated)
·进程从系统中消失。
· 常见终止情况:
· 正常退出(自愿)
· 错误退出(自愿)
· 严重错误(非自愿)
· 被其他进程杀死(非自愿)
3.4 进程通信方式
(1)管道/匿名管道(Pipes) :
· 用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。
· 半双工通信:数据只能单向流动
· 数据从管道一端写入,从另一端写出
(2)有名管道(Names Pipes) :
· 有名管道严格遵循**先进先出(first in first out)**。
· 名字存在内存中,内容以磁盘文件方式存储。
· 有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
(3)信号(Signal) :
· 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
· 信号可以在任何时候发给某一进程,无需知道该进程的状态
· 进程未处于执行状态,则信号由内核保存,知道进程回复
· 信号是软件层次上对中断机制的一种模拟,是异步通信。
(4)消息队列(Message Queuing) :
· 消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。
· 管道和消息队列的通信数据都是先进先出的原则。
· 消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。
· 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。
(5)信号量(Semaphores) :信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
(6)共享内存(Shared memory) :
· 使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。
· 内核中专门有一块内存区,由需要访问的进程将其映射到自己的私有空间。
(7)套接字(Sockets) :
此方法主要用于在客户端和服务器之间通过网络进行通信。
3.5 进程调度算法
为了确定首先执行哪个进程以及最后执行哪个进程以实现最大 CPU 利用率,计算机科学家已经定义了一些算法,它们是:
(1)先到先服务(FCFS)调度算法 : 从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
(2)短作业优先(SJF)的调度算法 : 从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
(3)时间片轮转调度算法 : 时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称 RR(Round robin)调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
(4)多级反馈队列调度算法 :前面介绍的几种进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程 。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。,因而它是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
(5)优先级调度 : 为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。
4 内存管理
4.1 概念
操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情。
4.2 内存管理方式
(1)块式管理 : 远古时代的计算机操系统的内存管理方式。将内存分为几个固定大小的块,每个块中只包含一个进程。如果程序运行需要内存的话,操作系统就分配给它一块,如果程序运行只需要很小的空间的话,分配的这块内存很大一部分几乎被浪费了。这些在每个块中未被利用的空间,我们称之为碎片。
(2)页式管理 :把主存分为大小相等且固定的一页一页的形式,页较小,相对相比于块式管理的划分力度更大,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址。
(3)段式管理 : 页式管理虽然提高了内存利用率,但是页式管理其中的页实际并无任何实际意义。 段式管理把主存分为一段段的,每一段的空间又要比一页的空间小很多 。但是,最重要的是段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。
(4)段页式管理机制 。段页式管理机制结合了段式管理和页式管理的优点。简单来说段页式管理机制就是把主存先分成若干段,每个段又分成若干页,也就是说 段页式管理机制 中段与段之间以及段的内部的都是离散的。
4.3 快表和多级页表
在分页内存管理中,很重要的两点是:
· 虚拟地址到物理地址的转换要快。
· 解决虚拟地址空间大,页表也会很大的问题。
4.3.1 快表
(1)目的
加快虚拟地址到物理地址的转换速度。
(2)实现
把快表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者全部内容。作为页表的 Cache,它的作用与页表相似,但是提高了访问速率。由于采用页表做地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。
4.3.2 多级页表
(1)目的
为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中。多级页表属于时间换空间的典型场景
(2)实现
页表一定要覆盖全部虚拟空间,使用多级可以减少第一级页表大小。
(3)原理
· 二级页表可以不存在。很多一级页表项没有用,则不用创建二级页表。
· 二级页表可以不在主存。某一时刻只有很少一部分二级页表在使用,可以把二级页表放在磁盘,在需要时调入到内存。
4.4 虚拟地址空间
4.4.1 概念
逻辑地址(虚拟地址)和物理地址
我们编程一般只有可能和逻辑地址打交道,比如在 C 语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操作系统决定。物理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址。物理地址是内存单元真正的地址。
4.4.2 CPU寻址
现代处理器使用的是一种称为 虚拟寻址(Virtual Addressing) 的寻址方式。使用虚拟寻址,CPU 需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为 内存管理单元(Memory Management Unit, MMU) 的硬件。
4.4.3 目的
如果直接把物理地址暴露出来的话会带来严重问题,比如可能对操作系统造成伤害以及给同时运行多个程序造成困难。
4.4.4 优势
(1)程序可以使用一系列相邻的虚拟地址来访问物理内存中不相邻的大内存缓冲区。
(2)程序可以使用一系列虚拟地址来访问大于可用物理内存的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为 4 KB)保存到磁盘文件。数据或代码页会根据需要在物理内存与磁盘之间移动。
(3)不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存。
4.5 虚拟内存
4.5.1 概念
虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种有一片连续完整的内存空间的错觉。这样会更加有效地管理内存并减少出错。
虚拟内存的重要意义是它定义了一个连续的虚拟地址空间,并且 把内存扩展到硬盘空间。
4.5.2 局部性原理(2-8原则)
4.5.2.1 概述
我们的程序在执行的时候往往呈现局部性规律,也就是说在某个较短的时间段内,程序执行局限于某一小部分,程序访问的存储空间也局限于某个区域。
4.5.2.2 表现
(1)时间局部性 :如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据被访问过,不久以后该数据可能再次被访问。产生时间局部性的典型原因,是由于在程序中存在着大量的循环操作。
(2)空间局部性 :一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇聚存储的。
4.5.3 虚拟存储器
(1)基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行。
(2)在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大的多的存储器——虚拟存储器。
4.5.4 技术实现
虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。 虚拟内存的实现有以下三种方式:
(1)请求分页存储管理 :建立在分页管理之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将相应的页面调入到主存,同时操作系统也可以将暂时不用的页面置换到外存中。
(2)请求分段存储管理 :建立在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理方式就如同请求分页储存管理方式一样,在作业开始运行之前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装入新的段。
(3)请求段页式存储管理
4.5.6 页面置换算法
缺页中断:如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页面或段调入到内存,然后继续执行程序。
当发生缺页中断时,如果当前内存中并没有空闲的页面,操作系统就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。用来选择淘汰哪一页的规则叫做页面置换算法,我们可以把页面置换算法看成是淘汰页面的规则。
(1)OPT 页面置换算法(最佳页面置换算法) :最佳(Optimal, OPT)置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。但由于人们目前无法预知进程在内存下的若千页面中哪个是未来最长时间内不再被访问的,因而该算法无法实现。一般作为衡量其他置换算法的方法。
(2)FIFO(First In First Out) 页面置换算法(先进先出页面置换算法) : 总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰。
(3)LRU (Least Currently Used)页面置换算法(最近最久未使用页面置换算法) :LRU算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 T,当须淘汰一个页面时,选择现有页面中其 T 值最大的,即最近最久未使用的页面予以淘汰。
(4)LFU (Least Frequently Used)页面置换算法(最少使用页面置换算法) : 该置换算法选择在之前时期使用最少的页面作为淘汰页。
5 文件系统
5.1 文件命名
5.2 访问路径
5.3 磁盘分区
6 I/O
6.1 分类
IO设备分为块设备和字符设备。
· 块设备:固定大小块信息。硬盘、光盘、USB等
· 字符设备:键盘、鼠标等
6.2 IO设备形式
6.3 寻址方式
(1)内存映射IO
(2)直接内存访问
不管DMA控制器的物理地址在哪,它都能独立于CPU从而访问系统总线。