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