1 操作系统概述
操作系统是计算机系统中的一个系统软件,是配置在计算机硬件上的第一层软件,是对硬件系统的首次扩展。它们能以尽量有效、合理的方式组织和管理计算机的软硬件资源;合理地组织计算机的工作流程,控制程序的执行并向用户提供各种服务功能;使得用户能够灵活、方便地使用计算机,使整个计算机系统高效率运行。
操作系统的作用体现在以下三个方面:
(1)资源的管理者
- 进程/线程管理(CPU管理):进程线程状态、控制、同步互斥、通信、调度…
- 存储管理:分配/回收、地址转换、存储保护、内存扩充…
- 文件管理:文件目录、文件操作、磁盘空间、文件存取控制…
- 设备管理:设备驱动、分配回收、缓冲技术…
(2)向用户提供各种服务
在操作系统之上,从用户角度来看:操作系统为用户提供了一组功能强大、方便易用的命令或系统调用。
(3)对硬件机器的扩展
2 操作系统的特征
(1) 并发
并发(concurrency):指处理多个同时性活动的能力,在计算机系统中同时存在多个程序运行在单CPU上,宏观上这些程序同时在执行,微观上任何时刻只有一个程序真正在执行,即这些程序在CPU上是轮流执行的(逻辑上同时运行,实际上同一时刻只有一个程序在运行)
并行(parallel):与并发相似,但多指不同程序同时在多个硬件部件上执行,是物理上的同时运行(并行需要硬件支持,如多流水线、多核处理器或者分布式计算系统)
(2)共享
共享是指系统中的资源可供内存中多个并发执行的资源共同使用,资源共享有互斥共享和同时共享两种方式。
互斥共享:系统中的某些资源如打印机,可以提供给多个进程使用,但是在同一时间内,只允许一个进程访问该资源。把这种在一段时间内只允许一个进程访问的资源,称为临界资源,系统中的大多数物理设备都属于临界资源,在系统中必须配置某种机制,用于保证进程互斥的使用临界资源。
同时共享:在一段时间内由多个线程同时访问该资源(微观上这些进程对资源的访问是交替进行的),典型的可以供多个进程同时访问的是磁盘设备,还有一些可重入代码等。
并发和共享是多用户(多任务)操作系统的两个最基本特征,资源共享是以进程的并发执行为条件,同时系统不对共享资源实施有效的管理,协调好进程对共享资源的访问,程序也无法并发执行。
(3)虚拟
虚拟是把一个物理实体映射为若干个对应的逻辑实体,在操作系统中通过时分复用和空分复用技术实现“虚拟”。
多个进程能在同一个处理器上并发执行使用了时分复用技术,让每个进程轮流占有处理器,每次只执行一小个时间片并快速切换,在宏观上表现为每个进程在虚拟CPU上执行,实际只有一个物理CPU。
虚拟内存使用了空分复用技术,它将物理内存抽象为地址空间,每个进程都有各自的地址空间。地址空间的页被映射到物理内存,地址空间的页并不需要全部在物理内存中,当使用到一个没有在物理内存的页时,执行页面置换算法,将该页置换到内存中。在宏观上表现为每个进程有自己的地址空间,物理上共有一片物理内存。
(4)随机
操作系统必须随时对以不可预测的次序发生的事件进行响应并处理。
3 操作系统运行环境和运行机制
3.1 处理器运行模式
处理器即CPU从内存中取出指令,解码然后执行。处理器由运算器、控制器、一系列的寄存器以及高速缓存构成。寄存器可以分为两大类:
- 用户可见寄存器:高级语言编译器通过优化算法分配并使用之,以减少程序访问内存次数
- 控制和状态寄存器:用于控制处理器的操作通常由操作系统代码使用,在某种特权级别下可以访问、修改。常见的控制和状态寄存器有:程序计数器,指令寄存器,程序状态字。其中程序状态字(PSW)记录处理器的运行状态如条件码、模式、控制位等信息。
由于操作系统运行在多进程环境下,为多进程提供并发环境,多个进程之间共享操作系统的资源,从操作系统并发和共享这两个基本特征出发,要求操作系统提供一种保护与控制机制,保护用户程序之间以及用户程序与操作系统之间互不干扰。需要硬件提供相应的硬件机制来实现保护和控制:一方面,处理器应该具有特权级别,能在不同的特权级(用户级别和操作系统级别)运行的不同指令集合;另一方面硬件机制可将操作系统与用户程序隔离。
如下图所示,多数计算机有两种模式:内核态和用户态。软件中最基础的部分是操作系统,它运行在内核态(也称为管态、核心态)。在这个模式中,操作系统具有对硬件的完全访问权,可以执行机器能够运行的任何指令。软件的其余部分运行在用户态,只使用了机器指令中的一个子集,会影响机器的控制或可进行I/O操作的指令在用户态的程序中是禁止的。
同时将指令分为特权指令和非特权指令:
- 特权(privilege)指令:只能由操作系统使用、用户程序不能使用的指令
- 非特权指令:用户程序可以使用的指令
常用的特权指令:启动I/O、内存清零、修改程序状态字、设置时钟、允许/禁止中断等
常见的非特权指令:控制转移、算术运算、访管指令、取数指令等
操作系统为什么要分为用户态和内核态?
(1)运行在用户态下的程序不能直接访问操作系统内核数据结构和程序,限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络,保证程序的安全执行;
(2) 在CPU的所有指令中,有些指令是非常危险的,如果错用,将导致系统崩溃,比如清内存、设置时钟等,用户进程不能直接对系统进行操作,保证操作系统本身的健壮性和安全性
3.2 CPU状态之间的切换
从用户态到内核态只有唯一的方法:中断/异常/陷入机制
- 中断:当外围设备完成用户请求的操作后,会向CPU发送中断信号。这时CPU会暂停执行下一条指令(用户态)转而执行与该中断信号对应的中断处理程序(内核态)
- 异常:当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
- 系统调用:用户进程通过系统调用申请使用操作系统提供的服务程序来完成工作,比如read()、fork()等。
从内核态切换到用户态的方法:设置程序状态字PSW
一条特殊的指令:陷入指令(又称访管指令)提供给用户程序的接口,用于调用操作系统的功能(服务)。例如:int,trap,syscall,sysenter/sysexit。系统调用机制要使用陷入指令从用户态陷入内核态。
3.3 中断异常机制
中断异常机制的概念:CPU对系统发生的某个事件作出的一种反应,即CPU暂停正在执行的程序,保留现场后自动转去执行相应事件的处理程序,处理完成后返回断点,继续执行被打断的程序。中断异常是随机发生的,这个过程是由硬件来自动完成的,具有可恢复性,中断异常机制是操作系统的驱动力。
使用中断异常机制,操作系统可以及时处理设备发来的中断请求,可使操作系统捕获用户程序提出的服务请求,防止用户程序执行过程中的破坏性活动等等。
为什么要引入中断异常机制?
(1)中断的引入:为了支持CPU和设备之间的并行操作
当CPU启动设备进行输入/输出后,设备便可以独立工作,CPU转去处理与此次输入/输出不相关的事情;当设备完成输入/输出后,通过向CPU发中断报告此次输入/输出的结果,让CPU决定如何处理以后的事情
(2)异常的引入:表示CPU执行指令时本身出现的问题
如算术溢出、除零、取数时的奇偶错,访存地址时越界或执行了“陷入指令” 等,这时硬件改变了CPU当前的执行流程,转到相应的错误处理程序或异常处理程序或执行系统调用
在早期是不区分中断和异常的,都叫中断,由于发生的原因不同,处理的过程不同就有了中断和异常的区分。中断是由于外部事件引起的,比如I/O中断(Ctrl+C,打印机打印结束,磁盘读取结束等)、时钟中断(定时期结束,进程时间片结束等)、硬件故障(笔记本没电)等;异常是由于自身原因造成的,由正在执行的指令引发的,如系统调用、页故障/页错误、保护性异常、断点指令、其他程序性异常等。
总结:
类别 | 原因 | 异步/同步 | 返回行为 |
---|---|---|---|
中断 | 来自I/O设备、其他硬件部件 | 异步 | 总是返回到下一条指令 |
陷入Trap | 有意识安排的 | 同步 | 返回到下一条指令 |
故障Fault | 可恢复的错误 | 同步 | 返回到当前指令 |
终止Abort | 不可恢复的错误 | 同步 | 不会返回 |
3.4 系统调用机制
所有用户程序都是运行在用户态的,但是有时候程序确实需要做一些内核态的事情,例如从硬盘读取数据,或者从键盘获取输入等。而唯一可以做这些事情的就是操作系统,这时需要一个这样的机制使用户态程序切换到内核态。这种机制叫系统调用机制 ,在CPU中的实现称之为陷入指令(Trap Instruction)。
系统调用就是用户在编程时可以调用的操作系统功能,系统调用是操作系统提供给编程人员的唯一接口,使CPU状态从用户态陷入内核态,每个操作系统都提供几百种系统调用(进程控制、进程通信、文件使用、目录操作、设备管理、信息维护等)。
系统调用、库函数、API、内核函数的区别?
应用程序可以直接调用系统调用,但是通常下应用程序都是通过编程语言中的api接口或者函数库来直接的调用系统调用,在操作系统内核中提供了很多的内核函数,内核函数经过封装为c函数库或者其他语言的api接口中。系统调用对于内核函数而言是系统调用的处理程序,处理程序通过封装给用户程序来使用。函数库和api接口中有些不是系统调用,而是普通的函数;内核函数中有些函数是不开放给用户调用的。
系统调用机制的实现:
- 中断/异常机制:利用硬件,支持系统调用服务的实现
- 选择一条特殊指令:陷入指令(亦称访管指令),引发异常,完成用户态到内核态的切换
- 系统调用号和参数:每个系统调用都事先给定一个编号(功能号),每个进程都通过陷入指令陷入内核,需要通过编号来区分
- 系统调用表:存放系统调用服务例程的入口地址
4 大内核和微内核
大内核系统将操作系统的主要功能模块都作为一个紧密联系的整体运行在核心态,从而为应用提供高性能的系统服务。因为各管理模块之间共享信息,能有效利用相互之间的有效特性,所以具有无可比拟的性能优势。
为解决操作系统的内核代码难以维护的问题,于是提出了微内核的体系结构。它将内核中最基本的功能(如进程管理等)保留在内核,而将那些不需要在核心态执行的功能移到用户态执行,从而降低了内核的设计复杂性。而那些移出内核的操作系统代码根据分层的原则被划分成若干服务程序,它们的执行相互独立,交互则都借助于微内核进行通信。
在微内核结构下,操作系统被划分成小的、定义良好的模块,只有微内核这一个模块运行在内核态,其余模块运行在用户态。因为需要频繁地在用户态和核心态之间进行切换,所以会有一定的性能损失。