计算机基础课第 40 期分享
阅读本文大概需要 11 分钟
01
"操作系统"诞生
1940,1950 年代的电脑,每次只能运行一个程序,程序员在打孔纸卡上写程序,然后拿到一个计算机房间, 交给操作员。等计算机空下来了,操作员会把程序放入,然后运行,输出结果,停机。以前计算机慢,这种手动做法可以接受,运行一个程序通常要几小时,几天甚至几周。但上节说过,计算机越来越快,越来越快,指数级增长。
很快,放程序的时间 比程序运行时间还长,我们需要一种方式 让计算机自动运作,于是"操作系统"诞生了。
操作系统,简称 OS,其实也是程序,但它有操作硬件的特殊权限,可以运行和管理其它程序。操作系统一般是开机第一个启动的程序,其他所有程序都由操作系统启动。
02
"操作系统"发展
操作系统开始于 1950 年代那时计算机开始变得更强大更流行。第一个操作系统加强了程序加载方式,之前只能一次给一个程序,现在可以一次多个。当计算机运行完一个程序,会自动运行下一个程序,这样就不会浪费时间,找下一个程序的纸卡,这叫批处理。
电脑变得更快更便宜,开始在出现在世界各地,特别是大学和政府办公室。很快,人们开始分享软件,但有一个问题,在哈佛1号和 ENIAC 那个时代,计算都是一次性的,程序员只需要给那"一台"机器写代码,处理器,读卡器,打印机都是已知的。但随着电脑越来越普遍,计算机配置并不总是相同的,比如计算机可能有相同 CPU,但不同的打印机。这对程序员很痛苦。
不仅要担心写程序,还要担心程序怎么和不同型号打印机交互,以及计算机连着的其他设备,这些统称"外部设备"。和早期的外部设备交互,是非常底层的,程序员要了解设备的硬件细节。加重问题的是,程序员很少能拿到所有型号的设备来测代码,所以一般是阅读手册来写代码,祈祷能正常运行。现在是"即插即用",以前是"祈祷能用"。
这很糟糕,所以为了程序员写软件更容易,操作系统充当软件和硬件之间的媒介,更具体地说,操作系统提供 API 来抽象硬件,叫"设备驱动程序"。程序员可以用标准化机制和输入输出硬件(I/O)交互。比如,程序员只需调用 print(highscore),操作系统会处理输到纸上的具体细节。
到 1950 年代尾声,电脑已经非常快了,处理器经常闲着,等待慢的机械设备(比如打印机和读卡器)程序阻塞在 I/O 上,而昂贵的处理器则在度假,就是放松啥也不做。50年代后期,英国曼彻斯特大学 开始研发世界上第一台超级计算机—Atlas,他们知道机器会超级快,所以需要一种方式来最大限度的利用它。
他们的解决方案是一个程序叫 Atlas Supervisor于1962年完成。这个操作系统不仅像更早期的批处理系统那样,能自动加载程序,还能在单个 CPU 上同时运行几个程序,它通过调度来做到这一点。假设 Atlas 上有一个游戏在运行,并且我们调用一个函数 print(highscore),它让 Atlas 打印一个叫 highscore 的变量值,让朋友知道我是最高分冠军。print 函数运行需要一点时间,大概上千个时钟周期,但因为打印机比 CPU 慢,与其等着它完成操作,Atlas 会把程序休眠,运行另一个程序,最终, 打印机会告诉 Atlas, 打印已完成。
Atlas 会把程序标记成可继续运行,之后在某时刻会安排给 CPU 运行,并继续 print 语句之后的下一行代码,这样, Atlas 可以在 CPU 上运行一个程序,同时另一个程序在打印数据,同时另一个程序读数据。Atlas 的工程师做的还要多,配了4台纸带读取器,4台纸带打孔机,多达8个磁带驱动器,使多个程序可以同时运行,在单个 CPU 上共享时间,操作系统的这种能力叫"多任务处理"。
03
内存虚拟化
同时运行多个程序有个问题,每个程序都会占一些内存当切换到另一个程序时,我们不能丢失数据,解决办法是给每个程序分配专属内存块。举个例子,假设计算机一共有 10000 个内存位置,程序 A 分配到内存地址 0 到 999,而程序 B 分配到内存地址 1000 到 1999,以此类推。如果一个程序请求更多内存,操作系统会决定是否同意,如果一个程序请求更多内存,操作系统会决定是否同意,如果同意,分配哪些内存块。这种灵活性很好,但带来一个奇怪的后果,程序 A 可能会分配到非连续的内存块,比如内存地址 0 到 999,以及 2000 到 2999。
这只是个简单例子,真正的程序可能会分配到内存中数十个地方,你可能想到了,这对程序员来说很难跟踪。也许内存里有一长串销售额,每天下班后要算销售总额,但列表存在一堆不连续的内存块里。为了隐藏这种复杂性,操作系统会把内存地址进行 "虚拟化",这叫 "虚拟内存"。程序可以假定内存总是从地址0开始,简单又一致,而实际物理位置被操作系统隐藏和抽象了,一层新的抽象。
04
动态内存分配
用程序 B 来举例它被分配了内存地址 1000 到 1999,对程序 B 而言,它看到的地址是 0 到 999,操作系统会自动处理虚拟内存和物理内存之间的映射。如果程序 B 要地址 42,实际上是物理地址 1042。
这种内存地址的虚拟化 对程序 A 甚至更有用。在例子中,A 被分配了两块隔开的内存,程序 A 不知道这点,以 A 的视角,它有 2000 个连续地址,当程序 A 读内存地址 999 时,会刚好映射到物理内存地址 999,但如果程序 A 读下一个地址 1000,会映射到物理地址 2000。这种机制使程序的内存大小可以灵活增减叫"动态内存分配"
05
内存保护
对程序来说,内存看起来是连续的,它简化了一切,为操作系统同时运行多个程序,提供了极大的灵活性。
给程序分配专用的内存范围,另一个好处是 这样隔离起来会更好,如果一个程序出错,开始写乱七八糟的数据,它只能捣乱自己的内存,不会影响到其它程序,这叫 "内存保护"。
防止恶意软件(如病毒)也很有用。
例如,我们不希望其他程序有能力,读或改邮件程序的内存。如果有这种权限恶意软件可能以你的名义发邮件,甚至窃取个人信息,一点都不好。
Atlas 既有"虚拟内存"也有"内存保护",是第一台支持这些功能的计算机和操作系统!
06
多个用户用"终端"来访问计算机
到 1970 年代,计算机足够快且便宜,大学会买电脑让学生用,计算机不仅能同时运行多个程序,还能让多用户能同时访问,多个用户用"终端"来访问计算机。"终端"只是键盘+屏幕,连到主计算机终端本身没有处理能力。
冰箱大小的计算机可能有50个终端,能让50个用户使用,这时操作系统不但要处理多个程序,还要处理多个用户,为了确保其中一个人 不会占满计算机资源,开发了分时操作系统。意思是 每个用户只能用一小部分处理器,内存等。
因为电脑很快,即使拿到 1/50 的资源也足以完成许多任务,早期分时操作系统中,最有影响力的是Multics(多任务信息与计算系统),于 1969 年发布。
Multics 是第一个,从设计时就考虑到安全的操作系统,开发人员不希望恶意用户 访问不该访问的数据。比如学生假装成教授,访问期末考试的文件,这导致 Multics 的复杂度超过当时的平均水准,操作系统会占大约 1 Mb 内存,这在当时很多!可能是内存的一半,只拿来运行操作系统。
Multics 的研究人员之一 Dennis Ritchie 曾说过,"阻碍 Multics 获得商业成功的一个明显问题是从某种方面来说,它被过度设计了,功能太多了"。
07
Unix
所以 Dennis 和另一个 Multics 研究员Ken Thompson 联手打造新的操作系统叫 Unix。他们想把操作系统分成两部分:
1.首先是操作系统的核心功能,如内存管理,多任务和输入/输出处理这叫"内核"。
2.第二部分是一堆有用的工具,但它们不是内核的一部分(比如程序和运行库)。
紧凑的内核意味着功能没有那么全面,Multics 的另一个开发者 Tom Van Vleck 回忆说:"我对 Dennis 说,我在 Multics 写的一半代码都是错误恢复代码",他说:"Unix 不会有这些东西,如果有错误发生,我们就让内核"恐慌"(panic),当调用它时,机器会崩溃,你得在走廊里大喊,"嘿,重启电脑"。
你可能听过 "内核恐慌"(kernel panic),这就是这个词的来源,内核如果崩溃,没有办法恢复,所以调用一个叫"恐慌"(panic)的函数。起初只是打印"恐慌"一词,然后无限循环。这种简单性意味着 Unix 可以在更便宜更多的硬件上运行。使 Unix 在 Dennis 和 Ken 工作的贝尔实验室大受欢迎,越来越多开发人员用 Unix 写程序和运行程序。工具数量日益增长。
1971 年发布后不久,就有人写了不同编程语言的编译器甚至文字处理器,使得 Unix 迅速成为1970~80年代最流行的操作系统之一。
08
个人电脑
到 1980 年代早期,计算机的价格降到普通人买得起这些叫"个人电脑"或"家庭电脑"。这些电脑比大型主机简单得多 主机一般在大学,公司和政府,因此操作系统也得简单。
举例,微软的磁盘操作系统(MS-DOS)只有 160 kB一张磁盘就可以容纳,于 1981 年发布,成为早期家用电脑最受欢迎的操作系统,虽然缺少"多任务"和"保护内存"这样功能,意味着程序经常使系统崩溃。虽然很讨厌但还可以接受,因为用户可以重启。
哪怕是微软 1985 年发布的早期 Windows虽然在 90 年代很流行,但却缺乏"内存保护",当程序行为不当时,就会"蓝屏",代表程序崩溃的非常严重,把系统也带崩溃了。幸运的是,新版Windows有更好的保护,不会经常崩溃。
如今的计算机 有现代操作系统比如 Mac OS X,Windows 10,Linux,iOS和Android,虽然大部分设备只有一个人使用。操作系统依然有"多任务, "虚拟内存", "内存保护",因此可以同时运行多个程序:一边在浏览器看 YouTube,一边在 Photoshop 修图,用 Spotify 放音乐,同步 Dropbox。
如果没有操作系统这几十年的发展,这些都不可能,当然,我们也需要地方放程序,我们将在下一节讲。
相关阅读:
-
计算机芯片的发展
-
算法入门