引言
这一章会讲解很多的操作系统概述,由于不是复习的重点,主要是为了引入一些概念,以及一些背景,所以将几个章节内容压缩到一篇当中。
操作系统的目标和功能
这里不做过多的讲述,直接上百度词条。
操作系统(Operating System,OS)是一种内置的程序,用来协作计算机的各种硬件,以与用户进行交互。
很显然,操作系统的作用是承上启下的。它作为一种内置程序,既操作并协调各种硬件,又为上层应用提供服务。
这里没有像百科中说以与用户进行交互
,主要原因如下图所示:
这张图里面,操作系统并不是直接和用户打交道,用户属于是最最上层的使用者,他们通过各种应用程序来实现交互,比如微信、wps等,往往也不直接和OS打交道。
这里将应用分为系统应用和应用程序,主要的区别是
- 系统应用主要指在操作系统级别运行的应用,负责管理硬件资源和提供系统服务。它们通常与操作系统紧密集成,为其他应用程序提供核心功能。例如,文件系统管理器、设备驱动程序和系统服务守护进程等。
- 应用程序则是指在这些系统服务之上运行的软件,它们通过系统级应用提供的接口与用户进行交云,并执行特定的任务。例如,文字处理软件、网络浏览器或者游戏等。
此外,我们再关注一下上图中的“应用开发者”和”系统设计者“。
- 应用开发者,简单来说就是程序员,而且是偏向OS的硬件开发人员。比如说,我们之前计组实验中的Verilog开发,暑期学校中对于maquesOS的开源项目,都是应用开发者。
- 系统设计者,那就是设计计组涉及的硬核电路板,数电模电中间的二极管、cmos管等人员
操作系统的演变
这里话不多说了,一般很少会有题目直接考OS的历史的,了解一下即可。
单道处理系统(Uniprogramming)
CPU一次只能执行一个命令,其余时间等待用户输入。
现在OS基本都是多道操作系统了,不然你怎么可能边听歌边写作业。
如果说有哪些例子,最简单的就是我们Windows下的命令行cmd/powershell。
多道批处理系统(Multiprogramming)
所谓的多道,就是内存中同时存放几个作业,宏观上并行运行,微观上串行运行
- 无序性:由于并行导致执行顺序不可预测
- 调度性:两次调度
- 作业调度
- 进程调度
评价指标
- Throughput rate(吞吐量):单位时间内完成的作业数目
- Turnaround time(周转时间):作业进入系统到完成所经历的时间
- 资源利用率:包括CPU、外设和内存等
CPU的利用率=1-p^n,其中p是一个程序等待I/O的时间占其运行时间的比例,n是多道程序度
例:2MB内存,OS占0.6MB,每个用户进程占0.4MB,进程等待I/O的时间占比为80%。CPU的利用率是多少?
答:根据公式,我们确定p是进程等待I/O时间的占比,题目给定是80%,而多道程序度n,它则是内存同一时刻可以容纳的最多的程序数,即(2-0.6) / 0.4 = 3,这里向下取整得到3。
所以,利用率η = (1-0.83)* 100% = 0.488 * 100% = 48.8%
分时操作系统
早期代表:Compatible Time-Sharing System (CTSS)
Time Slicing 时间分片
当控制交给用户,用户程序、数据被加载到内存,时钟每隔0.2秒产生一次中断
每次中断OS先获得控制权,再将处理器赋予另一用户
Timing 分时
分时的含义:分时是指多个程序分时共享硬件和软件资源(即:多任务),多个用户分享使用同一台计算机(即:多用户)
把计算机的系统资源(尤其是CPU时间)进行时间上的分割,每个时间段称为一个时间片(time slice),每个用户依次轮流使用时间片。
分类
- 单道分时:调入-调出(Roll-in/Roll-out),I/O开销太大
- 前台后台分时:后台存放批处理作业;内存的划分是固定的,不灵活
- 多道分时:需要解决加载程序时地址空间重定位的问题多道批处理系统
实时操作系统
主要用于过程控制、事务处理、信息查询等有实时要求的领域,其主要特征是实时性和可靠性。
特征
- 实时时钟管理
- 快速中断、调度
- 过载保护高度
- 可靠性和安全性
此外,现代还有嵌入式OS和分布式OS,不做过多阐述
现代操作系统的特征
- 并发(Concurrency)
- 共享(Sharing)
- 异步性(Asynchronism)
- 虚拟(Virtualization)
- 持久性(Persistency)
- 并发
注意,并发和并行不是一个概念
- 并发说的是宏观上的交替进行,是multiprogramming
- 并行是在同一时刻运行,通常是multiprocessing
-
共享(sharing)
多个进程共享有限的计算机系统资源。
互斥共享:资源分配后到释放前,不能被其他进程所用。
同时访问(如可重入代码,磁盘文件)
资源分配难以达到最优化 -
异步性(asynchronism)
也称不确定性、随机性,指进程的执行顺序和执行时间的不确定性
- 进程的运行速度不可预知:多个进程并发执行,“时走时停”,不可预知每个进程的运行推进快慢
- 判据:无论快慢,应该结果相同—通过进程互斥和同步手段来保证
- 难以重现系统在某个时刻的状态(包括重现运行中的错误)
- 性能保证:实时系统与分时系统相似,但通过资源预留以保证性能
- 虚拟(Virtualization)
- 一个物理实体映射为若干个对应的逻辑实体(分时或分空间)
- CPU为每个用户(进程)提供的"虚处理机"
- 存储器—每个进程都占有的地址空间(指令+数据+堆栈)
- 显示设备—多窗口或虚拟终端(virtual terminal)
- 持久性(persistency)
- 磁盘、固态盘
- 文件系统可以长期存储信息
- 文件系统支持把数据方便地从磁盘等存储介质上存入和取出
系统接口
系统调用
系统调用(system call)是OS提供给用户的接口,可利用它使用系统功能。
看过我上一章第二节的小伙伴应该清楚,我们在中断的时候提到了它,它是一个非常重要的OS概念。
OS内核有一组实现系统功能的过程(函数),系统调用就是对上述过程(函数)的调用。
系统调用把应用程序的请求传达给内核,内核调用对应的内核函数完成请求所需处理后,再将处理结果返回给应用程序。
说白了,就是OS在操作和管理硬件的时候为我们封装了一些接口,当这些接口函数被我们调用,即发生了系统调用。
如图所示,应用程序、库函数和系统调用是计算机编程中不同层次的概念,它们之间有着紧密的关联,但又有各自的功能和作用。
-
应用程序(Application Program):
- 应用程序是由程序员或开发人员编写的,用于解决特定问题或提供特定功能的软件程序。
- 应用程序可以是各种类型,如文本编辑器、游戏、浏览器、办公套件等。
- 应用程序通常是最终用户与计算机系统交互的主要方式,它们提供用户界面,接受用户输入,并执行各种操作。
-
库函数(Library Function):
- 库函数是一组预先编写好的函数或例程,可供程序员在应用程序中调用以完成特定任务。
- 库函数可以包括标准库函数(例如C语言的标准库函数,上图中的fprintf和write)、第三方库函数(例如Python的NumPy库)、操作系统提供的库函数等。
- 库函数的目的是为了提供可重用的代码,减少代码的冗余性,并简化应用程序的开发过程。
-
系统调用(System Call):
- 系统调用是操作系统提供给应用程序的接口,允许应用程序与操作系统内核进行交互和控制。
- 通过系统调用,应用程序可以请求操作系统执行底层任务,如文件操作、进程管理、内存分配等。
- 系统调用是操作系统提供的安全方式,用于让应用程序访问系统资源和硬件设备,而不会破坏系统的稳定性和安全性。
关系:
- 应用程序通常会使用库函数来执行特定的任务,而不必从头开始编写所有代码。这样可以提高开发效率。
- 库函数通常会使用系统调用来与操作系统进行通信,以便访问底层资源和执行系统级任务。
- 系统调用是应用程序与操作系统之间的桥梁,允许应用程序利用操作系统提供的功能。
总之,应用程序构建在库函数之上,库函数又可以利用系统调用来与操作系统进行交互。这三者之间的协作使得计算机软件能够有效地运行并实现各种功能。
分类
- 设备管理:设备的读写和控制;
- 文件管理:文件读写和文件控制
- 进程控制:创建、中止、暂停等控制;
- 进程通信:消息队列、共享存储区、socket等通信渠道的建立、使用和删除;
- 存储管理:内存的申请和释放;
- 系统管理:设置和读取时间、读取用户和主机标识等
实现过程
如图示,我们看到系统调用的过程和中断十分相似。
他们都有保护现场,寻找子程序(中断向量地址)和恢复现场等过程。
实际上,系统调用的执行过程是通过中断实现的,使用到的中断属于“软件触发的硬中断” ,属于陷阱(异常),即同步中断,而不是通常意义上的的中断(硬件中断)。
因为系统调用过程是要同步处理的,不能使用异步的软中断方式实现。
以下是基本的系统调用流程
- 系统调用通过指令触发异常(这里的异常是一个过程,实际上就是同步中断——从应用程序被打断,陷入内核态,到执行完后又恢复回来。对于异常的几种子类而言,基本都是这个流程)
- 陷入内核态,触发异常处理程序(在异步中断中叫中断处理程序),这个异常处理程序的内容就是进行系统调用(通过在 EAX 寄存器获取系统调用号,查系统调用表得到系统调用实现方法的基地址,执行系统调用方法)
- 执行完异常处理程序后恢复到被中断执行的指令。
在 linux 中执行 cat /proc/interrupts
会打印所有注册的硬中断,仔细观察之后,你会发现其中包含一个名为‘CAL’的中断,它就是系统调用所对应的中断号。这是通过执行机器指令触发的,所以我才说它是软件触发的硬中断。
系统调用与函数调用的异同
相同点:
- 改变指令流程
- 重复执行和公用
- 改变指令流程后需要返回原处
不同点:
- 系统调用是动态调用,而函数调用方式是静态调用
- 系统调用是动态调用,程序中不包含被调用代码。
系统调用的调用地址和返回地址都是不固定的。系统调用指令中不包含调用地址,只包含功能号。系统调用返回指令中不包括返回地址,通过栈保存和弹出返回地址。 - 函数调用方式是静态调用,被调用代码与调用代码在同一程序之内。
函数调用其调用地址是固定的,包含在调用语句中;
返回地址是不固定的(同一子程序可能被不同处多次调用),在程序执行过程中通过栈的实现来保存和弹出返回地址。
- 执行状态不同
调用和返回经历了不同的系统状态。通常OS核心和应用程序的代码分别运行在CPU的不同的状态下(核心态/系统态/管态和用户态/目态),所用地址空间也不同—核心的代码可以直接访问应用进程的地址空间,反之不然。 - 进入方式不同
利用int或trap指令进行系统调用;
利用call或jmp指令进入普通的过程调用 - 与进程调度的关系不同
采用抢占式调度的系统,在系统调用返回时,要进行重新调度的检查—是否有更高优先级的任务就绪(创建或唤醒)。 - 嵌套或递归调用
对系统调用,一般不允许在同一个进程中发生嵌套或递归(不同进程可以重入同一个系统调用)。
总结
最后,我们来简单的总结一下本章的内容,看到这里的小伙伴可以回顾一下之前说的。
- 操作系统的目标和功能
服务、功能、内核 - 操作系统的演变
- 简单批处理系统:监督程序、用户态 、核心态
- 多道批处理系统:多道程序设计技术、吞吐量、周转时间、CPU利用率、作业调度、进程调度
- 分时系统:交互性、分时、时间片、响应时间
- 现代操作系统的特征
并发、共享、异步性、虚拟、持久性 - 操作系统提供的用户接口
系统调用