熟肉视频地址:

第一节课主要是关于课程介绍以及操作系统是什么、为什么这么重要的简介。现代最伟大的发明之一是互联网,它把全世界不同规模的设备都通过统一的网络连接在了一起:
image

互联网的发展很迅猛,像最初的ARPANET,不能处理超过256个设备,大概是在90年代初万维网开始发展的时候,互联网突然变成了很多人可以使用的东西,现在我们的互联网上大概有 45 亿台设备,覆盖了世界的 60% 的人口。另一件有趣的事情是在这张图片中也有设备的多样性:
image

我们再来看看贝尔定律,他表示一个人拥有的设备的数量:

image

最初,数百万人使用一台计算机,然后随着发展,现在你们每个人可能都有数百个设备在为你们工作,比如现代汽车有数百个处理器,你们都有手机,笔记本电脑等等。每个人的电脑数量随着电脑的大小变小而增加,这很有趣。

如何让这么多系统正常运作并且连接在一起,我们就要考虑这个耗时尺度的问题:
image

这个图也是大家经常能看到的,大小越小的存储离 CPU 越近访问速度越快,大小越大离 CPU 越远访问速度越慢。不管怎样,操作系统必须在这些不同的耗时尺度正常运作,让系统正常运行。

image

操作系统基本上是所有这些的核心,你在底层技术上不断取得令人难以置信的进步的同时,会造成每个设备都有一些不同的差异性,每一代技术的发展都会有所不同,但是不管硬件有多复杂,你都要为应用程序提供一个一致的编程抽象;同时,需要管理不同应用之间的资源共享,我们连接的设备越多,可以共享的资源就越多。另外,到这学期的最后三分之一的时候,我们将开始讨论其中的一些非常有趣的点对点系统,这样我们可以拥有跨越许多设备的巨大存储系统。

我们会学习操作系统的关键组成:

  • 进程
  • 线程,并发,调度,协调
  • 地址空间
  • 保护,隔离,共享,安全
  • 通信,协议
  • 持久化存储,事务,一致性,弹性
  • 设备接口

image

在你想访问一个网页的时候,背后发生了什么?首先,会发出一个 DNS 请求试图找出这个网站的 IP 地址,这个请求会到网络上的 DNS 服务器,他们会返回有用的信息,之后使用这些信息,将实际网页请求发出;经过网络路由,之后它可能会被送到一个有负载均衡器的数据中心;然后将从几个可能的设备中选择一个可用的设备;然后,它可能会从页面存储中进行搜索和检索信息,把它拼成你可以用的页面之后返回。一旦我们开始深入思考这个流程中的细节,就会有很多有趣的问题,比如 DNS 服务器是如何保持一致的,为什么很难黑进它们呢?事实上,在 2000 年中期,有人侵入了它们。还有就是你如何确保数据包有足够的优先权当它们进入一个操作系统时,确保你的特响应查询不会被延迟很长时间,这是一个调度相关的问题。希望在这堂课结束时,你将对操作系统的各个部分有足够的了解,能够帮助你对这些问题有更好的理解。

image

那什么是操作系统呢?这方面其实没有统一的概念,但是我们可以从操作系统做的事情来理解什么是操作系统。操作系统负责:

  • 内存管理
  • IO管理
  • CPU 调度
  • 通信
  • 多任务处理或多处理器编程

操作系统和什么有关呢?文件系统?多媒体系统?用户界面?还有浏览器?

image

对于操作系统的定义,我们很难给出,一个近似的定义是当你订购操作系统时供应商提供的所有东西,但是不同的供应商提供的东西差别很大,它可能是电脑上一直在运行的一个程序即内核(kernel),随着学期的进行,你们会学到很多关于内核的知识。没有人会否认内核是操作系统的核心,但是当我们试图深入研究什么是操作系统时,你们要记住,我们要讲的是它的作用和重要的部分,但也许你永远不会完全知道到底操作系统是什么。

image

其实操作系统可以理解为是一个典型的软件层,它提供应用程序对硬件资源的访问,这是对复杂硬件设备的方便抽象以及对共享资源的受保护访问通信,以及提供安全性保护认证

image

操作系统,什么是"操作"呢?在早期,当你打电话时,他们实际上必须把你插到正确的连接上,让电线连接起来;然后是早期的计算机,需要计算机操作员,他们基本上是长时间坐在这些大机器前的人,确保它运行正常,然后就会操作系统了。这个“操作”系统就是要保证磁盘运行正确,网络运行正常,或者显卡等等都运行正常。

image

那是什么构成了一个"系统"呢?一个系统是由许多相互关联的部分组成的,一般来说,他们协作实现的要比各部分本身的功能大得多,每个相互关联的部分都可能与其他部分相互作用,当然,复杂度也变成了至少是 n 的平方。我们必须想出 api 和其他聪明的技术来避免 n 平方的复杂度,因为事情已经足够复杂了。对于这些 api 的使用以及理解就是系统编程,系统编程是这门课很重要的一部分,在这门课上你会接触很多的系统编程。

image

对于硬件/软件接口:你有一个处理器,在处理器里有寄存器,这些寄存器指向内存的一部分,这样程序就能运行了;可能处理器里面还有缓存,但它并没有很大,缓存的作用就是让内存和磁盘这些大容量但是访问较慢的看上去可以像寄存器访问一样快,通过一定的缓存设计。在虚拟内存的设计中,还有页表和翻译后备缓冲可以帮助我们。当然还有各种存储,例如内存还有磁盘。还有有各种各样的设备,比如网络、显示器和输入等等。这些纷杂的硬件都有自己的复杂的硬件接口,但是操作系统将这些复杂的硬件接口统一抽象成软件接口,供应用程序使用。比如抽象出了处理器的计算元素,把一堆存储设备,比如磁盘,u盘和云存储,变成一个单一的抽象即文件系统,这样应用就可以很容易地使用而不用关心其中的内容(每一位数据)实际存储的位置。这些也是这门课的核心内容。

image

操作系统充当的第一个角色,就是魔术师这样一个角色。它会提供简单明了的物理资源抽象,它会以一种方式让你至少暂时认为你拥有无限的内存,你有一台完全专用于你的机器或一个处理器,它有更高级的对象,如文件、用户和消息。这样会让你写代码更容易写,例如如果没有文件这个对象,那么你操作的就是磁盘上的一堆块,而文件是磁盘上一堆单独的块的抽象,它们以某种方式与 inodes(索引节点)放在一起,形成一个文件。

image
这是一台普通的物理机,它有内存,有I/O,可能还有存储和网络。在它上面我们会放一个操作系统,我们现在正在学习这个。操作系统将处理器资源抽象成一个非常简洁的东西,即线程(Thread);我们将会有地址空间(Address Space),我们将会学习的不是在 DRAM 中分散在各处的一堆内存字节,而是一个干净的地址空间抽象,这将使我们能够把内存当作完全属于我们的,即使有多个程序在运行。我们将会有文件(File),而不是一堆单独的磁盘上的块。我们将会有套接字(Socket),而不是直接操作网卡。在这些线程,地址空间,文件和套接字之上,将会有进程(Process)抽象,这个进程抽象将给我们一个由操作系统提供的受限权限的执行环境,在里面跑我们编译好的程序。为了给你一个干净的环境来进行编程使用这些抽象资源,会有系统库(System Libraries)

为什么抽象这些中间层是必要的:如果你试图去掉所有中间层直接操作底层(有时在非常特殊的环境中会这样做),你会发现特别麻烦,因为不同的底层硬件接口是不一样。这些抽象虽然对于性能有一点点损耗,但是带来的是统一接口统一代码的便利性。

image
系统库被链接到你的程序中,然后由编译器运行,然后被转换成在程序中运行的机器码,然后在进程环境中执行它们。

image
在进程中有什么:

  • 一个进程有一个地址空间,也就是一块受保护的内存
  • 它有一个或多个线程,访问上面那些地址空间
  • 其他的系统状态(system state):包括打开的文件和套接字等等

image

这里有一个例子,是 MAC 系统的例子,你可以查看进程监视器或任务管理器。类似于或者你在 Linux 机器上面执行 ps -aux。你会发现,在你的机器上,有很多很多的进程在运行。大多数都在 sleep,但他们会在某一时刻唤醒,执行一些任务。

image

这是操作系统对于多个进程的管理,每个进程都有自己的一组线程、地址空间、文件和套接字,它们可能会运行一个带有自己链接库的程序,并且这些进程实际上互相保护自己不受其他进程影响的。操作系统将底层的硬件接口转换成应用程序接口,每个程序都有自己的进程,进程是一个受保护的运行环境

image

操作系统的另一个角色即裁判,管理进程之间的资源的隔离以及共享。

我们接下来看一个简单的例子,假设这个例子中只有一个处理器
image
假设我们有编译好的程序 1 (棕色)和程序 2(绿色),我们只有一个处理器(Processor,一个核心 core,我们目前认为一个处理器只有一个核心,在后续的课程中可能会有多核的情况,这里先不考虑),那么操作系统怎么让这两个程序看起来同时在运行呢?首先每个程序都有自己的进程,每个进程都有自己的全局唯一进程描述符(Process Identifier)。在内存中,进程 1 有自己的内存空间(棕色),进程 2 也有自己的内存空间(绿色),同时,内存中还有灰色的代表操作系统使用的一些内存空间。然后,处理器里面做的就是不断地进程切换,先从一个开始,例如进程 1,这时候处理器执行的就是程序 1 的代码,处理器中的寄存区保存的是程序 1 需要的内容,访问的就是进程 1 的内存空间。

然后,时钟周期到了,需要切换:
image
这时候,处理器将进程 1 的寄存器内容保存起来(这个涉及到线程控制块,后面的课程会说),加载进程 2 执行需要的内容到寄存器开始执行,然后访问的是进程 2 的内存空间。

如果进程 2 尝试访问不是进程 2 内存空间的内存,比如进程 1 的内存空间会发生什么呢?这时候就会发生 Segmentation Fault(core dumped)这个错误,然后进程就会被操作系统停止。

image

其实,操作系统这里提供了一个保护边界,虽然这些进程都在同一个硬件上运行,但是操作系统可以防止进程访问不该访问的地方,保护进程不受其他进程的影响

image
最后,操作系统也作为粘合剂提供一些必不可少的服务,也就是程序会用到的公共服务(common service),例如文件系统服务,可视化界面服务,网络服务等等。这些公共服务通常是与紧密链接的,你在写程序的时候使用这些库来使用这些服务

这样,我们第一节课的内容基本就讲完了,你也对操作系统有了一个基本的理解与概念,最后我们提一下是什么让操作系统令人兴奋和具有挑战性。

image

这就是操作系统令人兴奋的地方,世界是一个巨大的分布式系统,如图所示,所有的设备从一端横跨全球的大规模集群,到小型微机系统设备和物联网设备以及介于两者之间的所有设备。这就是为什么我认为操作系统是如此令人兴奋,因为只有正常的操作系统才能让一切正常工作。

image
你们肯定知道摩尔定律(这也是伯克利大学的教授提出的),即每 1.5 年左右晶体管数量会翻倍。

image
但是在 21 世纪初,这个速度还是减缓了,因为人们发现把这些晶体管越来越多地放到芯片上,在电容和功率方面遇到了问题。在过去,你可以等上几年就能得到相当于你现在使用的机器两倍的性能,在21世纪的某个时候,这种趋势突然停止了。这怎么办呢?突然间人们不得不制造多核处理器,并设计大量并行计算

image

功率密度,电容,很多东西都是导致人们突然制造多核的原因,而不是以让速度更快为目的的,但是速度确实提高了.但是,摩尔定律要结束了,虽然不是正式的结束,但是已经无法维持原来的增长了。但这并不意味着人们不再把许多设备挤在一起,用网络连接它们,这只是意味着网络变得更加重要,而网络正常工作的基石就是我们要学习的操作系统

另一件事是存储容量不断增长:

image

所以我们有更多的设备更多的存储空间,更多的设备更多的存储空间更多的人意味着对操作系统的需求更大,这就是为什么我们要学习操作系统的另一个原因。

image
但是,学习操作系统的是一件很有挑战的事情,挑战主要来自于复杂度。应用程序由许多软件模块组成,运行在许多不同硬件平台上的许多设备上,可能还会受到恶意攻击导致失败,通过在所有可能的环境和组件组合下测试来完善软件是不可行的,我们必须学习如何以基本可行的方式来构建这些复杂的系统。


hashcon
68 声望20 粉丝

Mycat和java jfr unit的核心贡献者,贡献过OpenJDK,Spring Cloud. Apache Bookkeeper. Apache RocketMQ等项目,后台leader