操作系统介绍
前言
操作系统中使用到的三个关键的概念是:
- 虚拟化(virtualization)
- 并发(concurrency)
- 持久性(peristence)
虚拟化
虚拟化技术是一种通用的技术,操作系统将物理资源(CPU、内存和硬盘)转换成更加通用、更强大且更易于使用的虚拟形式,所以有的时候操作系统也被称为虚拟机(virtual machine)。
操作系统提供了一系列的接口(API,Application Programming Interface),供应用程序调用来使用系统的资源,也就是系统调用(system call)。
最后,虚拟化技术让许多程序同时运行(从而共享 CPU)、让许多程序可以同时访问自己的指令和数据(从而共享内存)、让许多程序可以访问设备(从而共享磁盘等),所以操作系统扮演的角色就是资源管理器(resource manager),将系统内的资源如 CPU、内存和硬盘,公平高效或者以实现某种目的的分配好。
本书中的所有虚拟化都是狭义、基础的一种,指的都是对于单个 OS 中如何将物理资源虚拟化后供进程使用,并不是现代广义上的虚拟化,这里是 IBM关于虚拟化的文章,这里的虚拟化指的是将物理资源虚拟化后供多个 OS 使用。
虚拟化 CPU
如果你使用的是 windows 系统,可以使用 ctrl+shift+esc 来打开 windows 的资源管理器,你可以看到有大量的进程正在你的操作系统中运行,他们看起来能够同时在你的系统中运行,你可以一边编译或者运行你的程序,一边听着音乐享受旋律,一边看着 youtube 上面的视频看看这个世界,操作系统将单个 CPU(或者其中的一小部分,这里指多核 CPU 中的单个核心)转换为看似无限数量的 CPU,从而使得多个程序能够看似同时运行,这就是所谓的虚拟化 CPU(virtualizing the CPU)。
但现在仍然有其他问题需要解决,如果两个程序现在同时想在特定的时间运行,我们的系统应该先运行哪一个,这个问题由操作系统的策略(policy)来回答,这些我们会在后面讨论。
虚拟化内存
现代计算机提供的物理内存非常简单,内存就是一个字节数组。如果要读取(read)内存就要指定一个地址(address),如果要写入(write)或更新(update)内存则需要指定的地址和需要写入的数据。假设我们现在有一个程序使用 malloc 函数申请内存并输出内存地址的程序,然后我们同时运行这个程序几次,那么我们就有可能看到多个进程被操作系统分配到了相同的内存地址,并能够向其中存入数值在读取数值时也能读取到先前存入的值,所以可以见得对于正在运行的程序,它们完全拥有自己的物理内存,但实际上物理内存是系统共享的资源,这些便是虚拟化内存完成的。
并发
假设我们现在有两个线程访问同一个共享全局变量,每个线程都对这个变量进行自增的操作,循环 100000 次,但是最后输出这个共享全局变量的值,我们会发现这个值并不是我们期待中的 200000,这种奇怪的问题是由于指令的执行顺序导致的,一个自增的操作实际上是由三条指令完成的,分别是:
- 加载计数器的值从内存中加载到寄存器中
- 将其递增
- 将值存回内存中
所以自增这个操作并不是以原子方式(atomically)执行的,便导致了问题的发生。这种并发的问题我们将会在后面进行详细讨论。
持久化
在系统内存中,数据容易丢失,因为像 DRAM 这样的设备是使用易失(volatile)的方式存储数据。如果断电或者系统崩溃,那么内存中的数据就会全部丢失。因此我们需要硬件或者软件来持久地(persistently)保存数据。
硬件是以某种输入/输出(Input/Output,I/O)设备的形式出现。现在计算机一般使用的都是固态硬盘(Solid-State Drive,SSD)来作为持久化设备,如果是一些大容量的场景会使用硬盘(Hard Drive)来做持久化。
操作系统中管理持久化设备的软件通常称为文件系统(file system),它负责以高效和可靠的方式来将用户创建的文件和其中的数据存储在持久化设备中。不同操作系统为 CPU 和内存提供的抽象,操作系统通常不会为每一个程序都创建一个专属的虚拟持久化设备,相反,它通常假设用户需要共享文件中的数据。比如以 C 语言为例,在编写程序的时候我们通常会使用 IDE 创建一个源文件,然后在文件中写入源程序,然后使用编译器编译这个源文件得到可执行程序文件,最后再执行这个可执行程序。
当然完成持久化的背后使用到的技术,需要哪些机制和策略才能高效的实现,面对硬件和软件故障的时候我们应该怎么保证可靠性,这些具体的细节我们会在后续进行讨论。
设计目标
到现在我们总结一下一个操作系统需要实现哪些功能:
- 虚拟化(virtualization),取得 CPU、内存或者磁盘等物理资源并将其虚拟化
- 并发(concurrency),处理并发有关的麻烦
- 持久化(persistence),持久地存储文件
除此之外,一个良好的操作系统还应该实现以下目标:
- 抽象(abstraction),为高层提供一个良好的简化模型,以隐藏底层的细节,使得系统易于使用
- 高性能(performance),最小化操作系统的开销
- 隔离(isolation),为进程之间和 OS 与进程之间提供保护,防止应用程序的不良行为会影响 OS 和其他应用程序
- 可靠性(reliability),操作系统需要不间断的运行,当它失效时,系统上运行的程序也会失效
其余的一些目标:
- 能源效率(energy-efficiency),环保
- 安全性(security),防止恶意程序获取敏感信息
- 移动性(mobility),在更小和系统资源更有限的设备中运行
操作系统发展
- 最早期:无操作系统时代(1940s-1950s)
- 计算机形态:真空管机器(如 ENIAC)
- 使用方式:手动操作,插拔电缆、开关输入程序。
- 特点:单用户,单程序;程序员直接面对硬件。
- 问题:使用效率极低;每次运行程序都要人工干预。
这一阶段基本没有”操作系统”的概念。
- 批处理系统(Batch Systems)(1950s-1960s)
- 背景:希望减少人工干预,批量运行程序。
- 技术进步:
- 作业(Job)概念:一组程序、数据、指令打包,交给机器一次性运行。
- 输入设备:打孔卡片、纸带。
- 代表系统:
- IBM 的 Mainframe 批处理操作系统(如 IBSYS)。
- 特点:
- 无交互;作业按顺序排队运行。
- 仍然是单道程序(一次只有一个程序跑)。
这个阶段开始出现了最原始的“操作系统”——负责简单的作业管理和设备控制。
- 多道程序设计(Multiprogramming)(1960s)
- 背景:CPU 速度远快于 I/O,单个作业经常因为等待 I/O 浪费大量时间。
- 核心思想:多个作业同时驻留在内存中,谁等待 I/O 时,就切换到另一个作业。
- 技术支撑:
- 内存管理(保护不同程序)
- 简单的调度(选择哪个作业运行)
- 代表系统:
- IBM OS/360
- Atlas Supervisor(早期非常先进的操作系统)
这一阶段奠定了“CPU 虚拟化”“内存保护”“作业调度”的基本模型。
- 分时系统(Time-Sharing Systems)(late 1960s)
- 背景:希望让多个用户同时使用同一台计算机(交互式使用)。
- 技术创新:
- 时间片(Time Slice)机制:每个用户分配一小段 CPU 时间。
- 虚拟终端(Terminal):通过电传打字机(Teletype)连入主机。
- 代表系统:
- CTSS(Compatible Time-Sharing System,MIT)
- Multics(Multiplexed Information and Computing Service)
- 特点:
- 交互式体验出现。
- 引入了用户账户、权限、安全机制的初步设计。
- 对后来的影响:
- Multics 影响了 Unix 的诞生。
分时系统让“虚拟化”“安全性”成为标准特性,真正意义上的现代操作系统诞生了。
- 个人计算机操作系统(1970s-1980s)
- 背景:计算机硬件价格下降,个人电脑(PC)兴起。
- 重要事件:
- 1970s:UNIX 在 Bell Labs 诞生(Dennis Ritchie 和 Ken Thompson)。
- 简单、优雅、可移植(用 C 语言编写)。
- 1980s:MS-DOS 诞生,随后 Windows 1.0 发布。
- 1970s:UNIX 在 Bell Labs 诞生(Dennis Ritchie 和 Ken Thompson)。
- 特点:
- 单用户(初期 PC 不考虑多用户)
- 交互式 GUI 开始出现(如 Macintosh System Software)。
从大型机、时间共享,发展到个人电脑操作系统,使用者群体迅速扩大。
- 网络化和分布式操作系统(1980s-1990s)
- 背景:计算机联网成为趋势。
- 重要变化:
- 局域网(LAN)的出现。
- 远程文件访问、网络打印、分布式计算等需求增长。
- 代表系统:
- SunOS(支持网络文件系统 NFS)
- early BSD Unix(引入 TCP/IP 协议栈)
- 概念扩展:
- 网络透明性(Network Transparency)
- 分布式文件系统(如 AFS、NFS)
这一阶段操作系统开始支持远程访问、分布式资源管理。
- 现代操作系统(2000s 至今)
- 背景:移动计算、云计算、大规模并发成为主流需求。
- 特征:
- 多核处理器普及 ➔ 多线程调度、并发同步机制变得极为重要。
- 虚拟化技术 ➔ KVM、Xen、VMware(支持在同一物理机运行多个虚拟系统)。
- 云计算和容器 ➔ Kubernetes、Docker 崛起,操作系统需要支持轻量级隔离。
- 安全性极大加强 ➔ 沙盒(sandbox)、权限分离(capabilities)等机制。
- 代表系统:
- Linux(服务器、云)
- Windows NT 系列(桌面和企业)
- Android(移动设备)
- iOS(移动设备)
现代操作系统必须支持并发、分布式、虚拟化、安全性、能效管理等多个复杂目标。
时间线总结:
- 1940s-50s:手动操作 ➔ 无操作系统
- 1950s-60s:批处理 ➔ 作业控制
- 1960s:多道程序设计 ➔ 提升CPU利用率
- 1960s末:分时系统 ➔ 交互式体验、虚拟化
- 1970s-80s:UNIX诞生、PC操作系统起步
- 1980s-90s:网络化、分布式操作系统
- 2000s-Now:多核、虚拟化、移动、云计算时代