程序不会直接访问磁盘、显示器等外设,而是依靠操作系统提供的服务。所有应用对硬件的操作尝试都必须通过操作系统。

操作系统有两个基本功能:

  1. 防止硬件被失控的应用程序滥用
  2. 向应用程序提供简单一致的机制来控制复杂而大不相同的低级硬件设备

操作系统通过几个抽象概念来实现这两个功能,进程、虚拟内存和文件。文件是对 IO 设备的抽象表示,虚拟内存是对主存和磁盘 IO 设备的抽象表示,进程是对处理器、内存和 IO 设备的抽象表示。

操作系统

1.7.1 进程

进程是操作系统对一个正在运行的程序的一种抽象。 在一个系统上可以同时运行多个进程,而每个进程都好像在独占地使用硬件。

一个 CPU 看上去像是在并发地执行多个进程,这时通过处理器在进程间切换的机制(上下文切换)来实现对。

操作系统保持跟踪进程运行所需的所有状态信息,这种状态就是上下文,包括 PC 和寄存器文件的当前值以及主存的内容。

当操作系统决定把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保存当前进程的上下文,恢复新进程的上下文,然后将控制权传递到新进程。

从一个进程到另一个进程的切换是由操作系统的内核(kernel)管理的,内核是操作系统代码常驻主存的部分。它不是一个独立的进程,而是系统管理全部进程所用代码和数据结构的集合。

进程上下文切换

1.7.2 线程

一个进程实际上由多个线程的组成,每个线程都运行在进程的上下文中,并共享同样的代码和数据。

线程成为越来越重要的编程模型,因为多线程比多进程之间更容易共享数据,也因为线程一般来说都比进程更高效。

1.7.3 虚拟内存

虚拟内存为每个进程提供了一个假象,即每个进程都独占地使用主存。每个进程看到的内存都是一致的,称为虚拟地址空间

虚拟地址空间

每个进程看到的虚拟地址空间由大量准确定义的区构成,每个区都有专门的功能。

虚拟内存的运作需要硬件和操作系统软件之间精密复杂的交互,包括对处理器生成的每个地址的硬件翻译。基本思想是把一个进程虚拟内存的内容存储在磁盘上,然后用主存作为磁盘的高速缓存。

1.7.4 文件

文件就是字节序列,仅此而已。 每个 IO 设备,包括磁盘、键盘、显示器,甚至网络,都可以看作文件。系统中的所有输入输出都是通过使用一组称为 Unix I/O 的系统函数调用读写文件来实现的。

文件的概念简单精致,它向应用程序提供了一个统一的视图,来看待系统中可能含有的所有各式各样的 I/O设备。

在 Linux 看来,一切皆文件。


我的思考

计算机里面概念的是抽象的,不管是对硬件的抽象,还是对软件的抽象。我的一位老师说过,抽象这个词就很抽象,它代表不具体的、高层次的,让人不能马上看懂。

这些都是系统底层的东西,应用层的程序员根本接触不到。我们的编程是在操作系统之上,大多数时候系统就是个黑盒,我们只要使用正确的 API 编程就行。

想要成为厉害的程序员,还是得了解底层啊,需要深入理解计算机系统。