小土刀

【计算机系统导论】6.1 操作系统的发展

操作系统的基本知识与发展简史,为后面的详细说明打下基础。


  • 操作系统概述(目标、功能、类型)
  • 操作系统的发展(串行处理、批处理、多道程序设计批处理、分时系统)
  • Windows/Unix/Linux 的历史
  • 主要成就(进程、内存管理、信息保护和安全、调度和资源管理、系统结构)

The OS Frame of Mind

The buck stops here

  • Nobody else to blame
    • No user action should crash the machine
    • Can’t just flee when the file system fills up
  • Central point of horror
    • “Exceptions” are not exceptional(zero divide, page fault, access violation - every second
    • Hardware devices wedge(maybe not daily)
    • Users will try to use 130% of everything

No way out

  • Customer or inmate
    • No (ordinary) user can steal another’s file
    • NO (ordinary) user can wipe out the entire file system
  • Controlled sharing
    • Memory quotas
    • Disk quotas
    • Task priorities
    • Packet scheduling

Failure is not an option

  • The disk block is bad
    • Retry, or map in another block
  • The whole disk is broken
    • RAID
  • A cosmic ray nuked the DRAM cell
    • ECC
  • Ethernet card ejected
    • Better traverse that ring buffer carefully

No rest for the weary

  • Completion is not a goal
    • OS should run “forever”(Maybe for entire lifetime of hardware)
  • Mistakes add up over time
    • Correctly handle 99.9% of clock interrupts
    • Leak 1 memory page per process exit

上世纪 80年代的时候,GUI 时代和个人计算机普及的时代降临了。从此,计算机变成了个人电脑,历史上第一次,计算机不是专为开发人员设计,而是为了普通用户设计。普通用户的需求就是完成一个一个的现实问题,软件产业提供的解决办法就是为用户提供一个一个的应用软件,而不是让用户自己一行一行的编程和写脚本,巨大的软件需求瞬间成就了一个巨大的软件产业。 这样的一个间接后果就是,对于普通用户来说,让一台计算机变成能够帮助自己完成任务的“个人计算机”的唯一手段,就是叠床架屋的不断的装各种应用软件。

操作系统发展历史

操作系统介绍

先简单回顾一下每一层的东西,然后开始介绍早做系统

定义:an intermediate program between a user of a computer and the computer hardware(to hide messy details)

目标

  • 执行用户程序以更轻松的解决问题
  • 使得计算机系统使用起来更加方便和高效


(系统应用与用户应用)

操作系统概念

  • 进程管理
  • 内存管理
  • 文件管理
  • 输入输出管理
  • 网络
  • 系统保护
  • Command-Interpreter System

编程珠玑番外篇-K. Plan 9 的故事(修订版)

(本文是对于之前编程珠玑番外篇系列中 Plan 9 的八卦这一篇的彻底修订,本文得到了博文视点的卢鸫翔编辑的很多帮助)
计算机发展史上,创新性产品层出不穷。其中,有些想法和产品在技术上很先进,却很遗憾的没有获得广泛的接纳和商业的成功。不过,只要时机到来,这些创新,往往都会以新的面目再次复兴。
这样的例子在历史中屡见不鲜。Jobs 和 Apple 分手后开创的 NeXT 公司的操作系统和硬件设备,创新点很多,市场反响却不大。而 NeXT 系统在软件和硬件设计上的创新,以及工业设计的思想,最终成为了现在 iOS 系统、Mac 系统软硬件设计的基石。同样是 Apple, 当年出品的 Hypercard 软件,首创了超文本格式和交互式页面。虽然 HyperCard 的这些创新在当时并不显得太出众,最终被苹果终止开发。但到了 Internet 出现之后,Tim Berners-Lee 受到这种“超文本 (hypertext)”格式的启发,将这些思想平移到联网的计算机上,由此出现了万维网。Ward Cunningham 更是受这一张一张的“数字卡片”受到,发展出了世界上第一个 wiki 系统 WikiWikiWeb。所有的这些例子,都说明了一项当时未必得到大多数人认可的创新可能会在意想不到的地方凤凰重生。 本节我们介绍的 Plan 9 操作系统,也是这样的一个例子。

FTPFS 虚拟文件系统
大部分读者应该都用过 FTP 在两台机器之间传送文件。FTP 是一种简单成熟的传输协议。试想现在我们需要修改一个 FTP 服务器上的文件,我们无法直接用本机上的编辑器打开这个远程的文件编辑,而需要先下载这个文件,修改后再上传。这种编辑远程文件的方法显然比编辑本机的文件麻烦多了。 我们退后一步仔细想一下这个不方便,会发现,文件是同样的一个文件,只是因为文件不在本地,我们需要借助于 FTP 协议访问,所以我们就不能直接编辑它了(事实上有些功能强大的编辑器如 VIM 仍然可以编辑,但普通的编辑器则不能)。在一切都是文件的假设下,我们可以不加区别的访问软盘,硬盘和闪存盘上的文件,但这里,因为中间多了一个网络协议,这种“一切都是文件”的方便特性就消失了。 因为这个需求很常见,很多 FTP 客户端,如 Windows 下的 LeapFTP, Mac 下的 Cyberduck,都做了一个贴心的功能,在你想要编辑远程文件的时候,自动将其下载成一个临时文件,等你修改结束后又自动上传。但是这依赖于 FTP 客户端,并不是每个客户端都提供了这类支持。

FTPFS 就是针对上面提出的这种不方便而出现的一种技术。通过利用一个叫做 FUSE (Filesystem in Userspace) 的技术,FTPFS 允许用户将远程的 FTP 文件系统挂载到本地的文件系统上,使得用户可以像操作本地文件一样操作远程文件1,包括查看,编辑,删除和重命名等等。而实际网络传输协议的细节,则对用户隐藏了。实际上,FUSE 技术可以用来实现很多“虚拟”的文件系统,而不仅限于将 FTP 文件系统挂载到本地文件系统上这一种。比如,使用 HTTP 协议的文件系统,SSH 服务器上的文件,Flicker 上的图片,维基百科上的文章,都可以通过 FUSE,抽象成一种虚拟的挂载在本地文件系统上的文件系统。这些虚拟的文件系统,隐藏了协议的细节,将各种不同类型的协议支持下的资源抽象成一个文件系统,也可以挂载到本地的文件系统上。

虚拟文件系统能把资源无差别的抽象成文件系统。这种做法消除了网络协议的不同造成的访问障碍,方便了用户对各种不同资源的访问。这种 “消除协议差异,一切资源都是文件”的思想,实际上来源于 Plan 9。毫不令人惊讶的是,在 Plan 9 中,干脆就没有 FTP 这个命令,所有对 FTP 的操作都是采用挂载 ftpfs 挂载文件系统的方式实现的。

一切都是文件(这次是真的)

上面我们提到了虚拟文件系统可以把资源无差别地抽象成一个文件系统,而这个思想是来源于 Plan 9 操作系统的。且慢,早在 UNIX Programming Environment 中, Brian W. Kernighan 就提出了 “UNIX 中,一切都是文件” 的设计哲学。事实上,UNIX 中的确很多对象是文件:进程是文件,设备是文件,命名管道也是文件。但是,也有很多不是文件,尤其是由其他非 Bell 实验室加入 UNIX 的组件。举例来说,计算机网络设备和服务不是文件(UNIX 的网络支持部分最先由 UC Berkerly 开发),图形界面中的对象也不是文件(UNIX 的图形界面支持最初由 MIT 的 X 工作组开发)。“一切都是文件” 这个口号因为 UNIX 的发展和新模块的加入而不再贴切。

UNIX 出现的时候,支持的设备都很简单,都可以抽象成文件交由内核统一管理,由内核提供 read/write 等系统调用访问设备。随着硬件的发展,一些新的硬件需要有超越系统调用范围的控制方式(例如我们可以控制光盘驱动器弹出托盘,而这个操作在传统磁盘驱动器上是不存在,也不能简单的抽象为 read/write 甚至 unmount 操作),或者为效率着想,需要用户空间程序直接和设备通信(如网卡,高速硬盘)。因为这些需求,和为未来扩展性考虑,Bell 实验室在 UNIX 第七版中,也不得不引入 ioctl 等具有无穷扩展性的系统调用机制,配合设备驱动程序,支持对设备的控制。这些做法,绕开了原先统一的 read/write 设备访问方式。也就是说,设备再也不能简单地抽象为文件了。

随着 UNIX 发展而失却的“一切都是文件”的纯粹哲学,正是 Plan 9 想要恢复的。在 Plan 9 中,通过实现一个叫做 9P 的文件协议,用户可以自由的把任何资源或服务抽象成本地的一个“虚拟的”文件或者目录,而对这些文件的操作,会通过 9P 协议,自动映射到对原来资源或者服务的操作。 这样,访问资源的各种细节就被隐藏了。在对付那些需要 ioctl 或者其他控制机制的设备或者应用程序时,Plan 9 提倡将程序的控制部分抽象成一个支持 read/write 的 ctl 文件,而非使用专门的 ioctl 系统调用。这样,其他程序就可以通过读写 ctl 文件与被控制的程序通信。从对资源和对控制的抽象不难看出来,Plan 9 把 UNIX 中“一切都是文件”的思想做了进一步的升华。在 Plan 9 里面,真的是一切都是文件了──设备是文件,窗口管理器是文件,Email 程序是文件(实际上所有程序都是文件),网络是文件(实际上所有服务包括 DNS 都是文件),等等。

Plan 9 的创新
要说 Plan 9 的特性,就不能不先介绍一下它的几个创造者。和 UNIX 一样, Plan 9也是从 Bell 实验室计算机科学研究中心开发的。其项目主要负责人是 Rob Pike (现在在 Google 工作,负责 Go 编程语言),当时在 Bell 实验室的很多人,包括 UNIX 的两位创始人,Ken Thompson 和 Dennis Ritchie ,以及 Brain Kernighan、Doug Mcllroy (UNIX 管道的提出者)都参与了这个项目的开发。从某种意义上来说,Plan 9 有点充当 UNIX 继承人的味道。事实上 Rob Pike 最初,也的确是想构建一个更加“现代的 UNIX”。除了坚持 UNIX 中已经成功了的“一切都是文件”,“KISS”等原则外,Plan 9 在原有 UNIX 的设计理念上做了新突破,其中最值得一提的,就是“分布式操作系统” 的理念。

Plan 9 这个分布式操作系统的出现和当时计算机发展的趋势是密不可分的。我们都知道, UNIX 是一种分时操作系统,用户分享机器资源。UNIX 操作系统则负责在各任务(或者说进程)之间调度。因此,UNIX 是一个中心化的操作系统。CPU、内存、IO 以及所有的任务的调度都是集中被 UNIX 管理的。上世纪 80 年代中期,更加便宜的微型计算机开始普及。这些微型计算机各自有着磁盘、CPU、内存和 IO 设备。Plan 9 的指导思想,就是把微机组织起来,方便的实现资源共享。

Plan 9 里,能共享的资源包括文件系统、图形界面、IO 设备、以及 CPU 和内存等计算资源。这些资源之间千差万别,我们固然可以针对每种资源设计一个协议,如文件分享用 NFS,图形界面用 X 协议,打印机用 CUPS 协议等等,不过这种做法在 Plan 9 的设计者看来是不够优雅的。他们采用的,是在上文我们已经提到过的“一切都是文件”的方法[cite:Plan 9, a distributed system]。我们可以用两个很有启发性的例子来说明。

例一、替换 CPU

假想一下我们有一台日常使用但性能不佳的笔记本,和一台不在本地但性能强劲的服务器。 我们当然能够使用远程计算机的强劲的 CPU 运行一些计算量特大的程序。这不是什么难事,因为几乎所有操作系统都支持登陆到远程的机器。然而,麻烦的是,如果在远程运行程序需要读写本地的文件,或者访问挂载在本地笔记本上的打印机,扬声器麦克风之类设备,我们除了在本地和远程之间把文件传来传去之外,并没有什么好方法。特别的,如果我们想借用另一台计算机上强劲的 CPU 做音频和视频解码,来播放一个放在本机光盘驱动器里的电影文件的话,我们是不可能指望远程计算机既能读本地的光驱,又能把音频投递到本机的扬声器上的。

Plan 9 中,有一个简单的 cpu 命令,能够让用户自然地使用一个其他机器上的 CPU 运行程序,且仍然能够访问本地的所有文件和设备。也就是说,我们可以用远程计算机上强劲的 CPU 做图像处理,媒体解码等任务,并且可以直接把声音播放到本地的扬声器。cpu 命令给人的感觉,是除了给机器换个了 cpu 外,其他一切都和原来一样。这个看似 “神奇” 的功能,其实在 Plan 9 里实现起来一点都不复杂: cpu 指令首先连接服务器上,然后将本地的所有资源和文件系统,包括窗口管理器,光盘驱动器,扬声器等设备(别忘了他们都是文件),一股脑儿挂载到服务器上,成为服务器上的资源。这样,在服务器上运行的程序,就可以“自然地”使用本地的键盘鼠标和显示器完成交互,还可以访问你本地的显示器扬声器等设备。

cpu 命令真的就是名副其实的换掉了本地计算机的 cpu (其实还有内存)而保留其他一切设备。Plan 9 的这个 cpu 命令,带有强烈的分布式操作系统的特征,而我们平时接触的操作系统都不是分布式操作系统,因此 cpu 这个命令至今在现代主流操作系统上没有完全等价物。

例二、进程间控制和通信

进程间通信可以提高使用计算机的效率(详细请参见 Page XX:开发人员为何应该使用 Mac OS X)。UNIX 下的管道就是一个经典的进程间通信的例子。在图形界面程序和集成化的程序出现后, 应用程序不断的把多种功能集成到一起,进程间通信反而变得相对困难了。比如说,即使有个给汉字加拼音的程序,除了来回复制粘贴,我们还是不能方便地从文字编辑程序中选取一段自动加上拼音。而 UNIX 下的编辑器可以借助管道很简单完成这样的操作。这个问题的本质困难,用操作系统的眼光来看,在于进程这个对象,没有在运行时暴露出应有的通信和控制接口。

Plan 9 的一切都是文件的思想从一个新的角度,解决了程序间的数据共享问题。Plan 9 倡导应用程序在运行时都把自己的内部状态抽象成一个文件系统。举例来说,一个邮件客户端程序不光支持图形界面下查看邮件,用户还能够直接通过

cat /mail/fs/inbox/1/subject
cat /mail/fs/inbox/1/body

来查看收件箱(inbox)中第一封邮件的主题和内容。这种设计,使得应用程序不再成为进程间通信的障碍,从而拷贝粘贴也变得没有必要。比如说,我们可以直接把草稿箱里邮件的内容通过管道送给其他拼写检查器。邮件客户端提供的拼写检查器再差也没关系了。这种把应用程序中的对象暴露出来的想法,和 Mac OS X 中的应用程序暴露一个Applescript 字典的设计思想异曲同工。

同样的道理,Plan 9 也从一切都是文件的思想出发,解决了了程序控制问题。 Plan 9 鼓励每个应用程序和设备在抽象成文件的时候,都暴露出一个抽象的 ctl 文件。这样,其他应用程序可以通过向 ctl 文件写命令的方式,运行时控制应用程序。举例来说,Plan 9 的窗口管理器 Rio,提供了 ctl 文件,我们可以通过读取和写入 ctl 文件,实现一些 Rio 本身不支持的如平铺所有窗口的操作。同样,通过对邮件程序的 ctl 操作,我们可以实现邮件的发送和接受的控制等等。Mac OS X 下的 Applescript 也可以完成类似的功能。遗憾的是,除了 Plan 9 和 Mac OS X,其他操作系统对这类进程间控制和通信的支持都不够完整。

实践者指南
上面介绍的 Plan 9 特性,可以说仅仅是冰山一角 Plan 9 里还有很多其他创新,如 Rio 窗口管理器简化了窗口管理,fossil 文件系统使增量备份毫不费力,/proc 文件系统方便对系统的控制和支持远程 debug 等等。我们可以在桌面通信的 DBus 标准,Mac OS X 的 Time Machine, Linux 的 /proc 文件系统里找到这些技术的影子。因为 Plan 9 从来就没有大众化,有不少创新不为外人所知。
对 Plan 9 感兴趣,想要更多了解 Plan 9 的读者,可以到 http://plan9.bell-labs.com/plan9/ 下载 Live CD, 并在多台联网的机器或虚拟机中安装该系统。喜欢 Plan 9 里的一些命令,而不想折腾系统的读者,可以到 http://swtch.com/plan9port/ 下载可以在 Linux,Mac OS X 等主流操作系统上运行的 Plan 9 的移植程序。Rob Pike 的网站 cat-v.org 有最完整的 Plan 9 的资料,以及对 UNIX 设计哲学的反思。

Plan 9 中的很多思想,如/proc sysfs,还有 userspace 的虚拟文件系统,对 IPC 的重新处理如 DBus ,轻量级别的窗口管理器,UTF-8 等等,实际上都融入了 Linux 等现代操作系统。对于 Plan 9 这样含有众多优秀设计思想的操作系统,为什么最终没有流行开来,自然是很多人关心的。 ESR 曾经说,可能是因为当时 UNIX 已经足够好了。这样的解释很容易让人想起那句著名的 Worse is better。具体是什么原因呢,就交给各位读者思考了。

UNIX 痛恨者手册读后笔记

UNIX 痛恨者手册读后笔记 http://blog.youxu.info/2011/10/14/notes-on-the-unix-haters-handbook/

UNIX 痛恨者手册[PDF]可以算是一本奇书了。一般的技术书,写作缘由大多是作者特别喜欢某样技术,兴高采烈地拿出来和读者分享。而此书的几个作者,都是因为恨 UNIX 恨到“人生长恨水长东”的境界了,于是乎搞了个邮件组,广泛收集各种愤怒,最后基于邮件组里面张贴的各种抱怨,编撰成了痛恨者手册这样一本书,来专门宣泄对 UNIX 的愤怒,也算得上是空前绝后了。
尽管这本书视角独特,以现在的眼光看,作者的抱怨中,真正属于 UNIX 固有问题的只占 50%,其他如对 sendmail 排山倒海的批评,对 C++ 的尽情嘲弄,实际上都不属于 UNIX 系统特有的。其他的 50%,则颇有历史意义,可以看到当年的 UNIX 系统是何其的“原始”。特别是对照现在的 Linux 来看,可以看出 Linux 作为当年 UNIX 的继承人,在文件系统,安全性,稳定性等等方面的巨大的进步。

除去一些对 UNIX 中具体 BUG 的批评,这本书的背后实际上是三种设计哲学间的交锋,我把这三种哲学叫做 MIT 哲学,UNIX 哲学和 GUI 系统哲学。“MIT 哲学”这个词,是借用那篇著名的 Worse is better 文章中的叫法。MIT 哲学的代表是 LISP 机器,即提供一个 LISP 环境的机器。这个机器提供给用户的,是优雅的编程环境,如统一的内存管理,统一的函数式接口,良好的文档等等,一切程序员所需要的,都给准备好了。但这个系统不管是作为个人计算机还是作为工作站都没有获得成功。

GUI 系统哲学从施乐的 Alto 开始,到90年代中期 Windows 95 出现之前,已经颇有气象,特别是在个人计算机领域,几乎所有的个人计算机厂商都在提供自己的图形界面操作系统。GUI 系统的哲学,是友好的用户界面和一致的使用体验。至于具体的功能,则委托给具体的应用程序实现。

而 UNIX 哲学,则像是一种开放式系统的哲学:除去提供统一的系统调用和标准工具外(POSIX),不强调系统的一致性。UNIX 像是一堆松散的积木堆起来的一个系统,在遵守 POSIX 标准的前提下(其实是个非常松散的标准)各个厂商都可以自己选择积木搭建系统。

UNIX 这种开放的,允许自由搭积木的做法,是和信奉MIT哲学的人水火不容的。这些用户在 UNIX 的因为开放造成的不一致性上尽情吐槽。比如说,UNIX 一个饱受诟病的缺憾是其命令行参数不统一。在命令行下,有的命令加 -h 是显示帮助,有的却是显示隐藏文件,还有的命令压根不接受 -h 参数。这样的问题,反映了 UNIX 在演化过程中缺少一个统一的规划。这在演化路径单一的其他操作系统上是不可想象的。再比如,UNIX 的计算模型很简单,即用 C 语言和 shell 对系统调用做一个胶水包装,不提供内存管理也不提供异常处理,文件系统也很低级,不支持文件恢复也不支持文件的元信息存储。而 MIT 的LISP 机器的计算模型和存储系统看上去都更加高级,统一的函数式接口,自动内存管理等等。用过 LISP 机器的人自然不习惯 UNIX 这种看上去“低级”的操作系统。结果是,用过 LISP Machine 的用户除了抱怨 UNIX 外,只能寻求在 UNIX 上构建一个新的层,来弥补 UNIX 的不足。这事情的一个结果就是造就了Emacs 这个怪兽,到最后几乎所有能在 UNIX 里做的事情,都能在 Emacs 里完成。这样,除了操作系统内核外,Emacs 完全取代了 UNIX 环境。Emacs 功能强大到大家都同意 Emacs 是个万能软件,而 vi 用户则开玩笑说 Emacs 是个缺少一个好编辑器的操作系统。大家都知道,Emacs 的作者正是从 MIT 出来的 Richard Stallman。

痛恨者手册的作者也是在 MIT 的 AI 实验室工作多年的技术人员。为了解释 UNIX 的成功,他借用了 Worse is better 中的说法(Garbriel 断言 C 语言和 UNIX 是终极计算机病毒),把 UNIX 归类为世界上第一个计算机病毒。书中提到,UNIX 和病毒的共同特征为:体积小,可传染多种宿主(可移植),变异快速等等。书中说, UNIX 的普及并不是因为它在技术比其他操作系统更加优越,只是因为可移植,可传染和变异快,才占据了很大一块用户份额。

这个解释我认为是相当精当的。相对于其他操作系统,UNIX 基于C书写,可移植和早期的免费分发方式,即使技术上不够好,仍然像流行性感冒一样蔓延。一传十,十传百,快速攻城略地。当时 UNIX 的风行程度可以从几个侧面来证明。八十年代初雨后春笋一般地冒出了很多新的UNIX公司,SUN 和 SGI 就是是借着 UNIX 成长起来的典型例子。他们短短几年间就靠 UNIX 工作站业务跑上了纳斯达克。微软和苹果是靠个人电脑业务起家的,各自都有自己的操作系统,却也跑到UNIX世界下注,都曾经推出过自家的UNIX发行版(分别叫做 Xenix 和 A/UX)。UNIX这个”病毒”在工作站和服务器上的寄生能力极强,直到后来演化能力和传播能力更强的“病毒” Linux 的出现,加上 .COM 泡沫破裂的一场大洗牌,才把 UNIX 的市场份额压了下去。Linux 则彻底继承了所有的“病毒”特性,除去原有的体积小,可移植外,通过开放内核源代码,造就了现在从超级计算机服务器到嵌入式系统无处不在的现状。从设备总量来说,世界上从未有一个操作系统如 Linux 如此成功。

可惜的是 MIT 哲学派本身没有成功的操作系统产品用来作为比较(除了Emacs这个运行在UNIX上的程序外),因此在批评 UNIX 上火力就欠缺了一分。为了写出一本厚厚的痛恨者手册砸向UNIX,就需要来自另外一派,即信奉GUI哲学的用户的愤怒。

这些用户的愤怒,主要集中在易用性上。图形界面操作系统的出现,本质上就是为了解决计算机的可用性问题。在图形界面系统出现之前,掌握计算机的使用需要的是阅读厚厚的手册。图形界面出现后,只需要几分钟的演示,普通用户即可操作计算机完成一些简单的任务。这种效率的本质提升,正是施乐的 Alto 和苹果的 Macintosh 的革命性所在。而 UNIX 所拥有的,是一堆两个字母的命令,不一致的命令行参数,和一个实际上不是为 GUI 系统设计的 X 图形系统。命令难记,X 又臃肿,即使有了这些仍然没有构成一个统一的桌面系统(所以后来才有KDE 和 Gnome),也难怪用户吐槽不已了。

在这类来自 GUI 用户的抱怨中,出乎我意料的一条是对UNIX管道的抱怨。主要的批评点在于管道作为一种 IPC 机制本身不够强大,包括管道不支持双向数据流(双向管道的用例也极少),只能把数据作为字节流而不能传递结构化数据,和指针等等。从传统 UNIX 用户的眼光来看,这些指责是很不公平的。管道的作用是串接程序的输入输出,将小工具串成强大的工具链。但管道并不是 UNIX 上唯一的 IPC 机制,UNIX 有其他的 IPC 机制来支持管道之外的功能。换一个角度看,要求管道支持双向通信,结构化通信等等,正是从 GUI 哲学出发的对管道的批判。在 GUI 世界,进程间的通信有了两种新的方式:1、把小程序全部集成到一个大的多线程窗口程序中来进行线程间通信; 2、通过在不同程序间复制粘贴对象。从这两个角度考虑,自然会要求 UNIX 管道能像线程间通信一样双向,以及支持有结构的对象而不是单纯的字节流。

GUI 程序的这一套新的进程间通信机制,改变了所在平台的软件架构。UNIX 的软件架构,是围绕软件工具(Software Tools) 的概念展开的,归结起来就是每个工具做一件事情,且做到最好的哲学。因为 GUI 程序本身的复杂性,把林林总总的功能,放入一个大程序中让各模块直接在一个进程空间里互相通信成了一个通行的做法。比如电子表格软件中的公式计算,无需代理到 bc 这样的外部计算器中,直接由内置的模块完成。在这种哲学的指导下,为了给提供全面的解决方案,各种商业程序都追求大而全,内置各种可能用到的功能,因此体积也越来越大。几百兆大小的商业软件不足为奇了。UNIX 痛恨者手册推崇这种只能算局部最优的程序构建方法,而反过来抱怨管道这个另一个局部最优不够好,在我看来是有历史局限性的。

总的来说,这本书代表了 UNIX哲学以外的其他两种哲学对 UNIX 尖锐的批评,是值得当成UNIX 发展史的一部分而一读的。


所谓的进程间通信 (IPC),就是两个程序之间的信息共享。 我们都知道,nix 的一个强大之处就在于管道,管道是最简单,最廉价也是最常用的 nix 进程间通信的方法。在 GUI 时代,最常用的 IPC 机制成了剪切板和鼠标拖放操作。这两个操作虽然都很直观,但都要人操作,离开了人,程序根本无法自动完成进程间通信。 而要工作效率的提高,就是要让计算机离开了人的干涉,也能完成这些任务。为了自动化这些任务,操作系统就不能简单的绘制窗口然后万事大吉了,它必须要知道哪些程序在运行,哪个运行的程序可以给哪个程序发消息通信等等,比如说,如果我们想自动的在阅读器里面选择一个词送给字典程序查释义,计算机就需要知道字典程序在运行的时候可以接受一个字符串,但是不可以接受图片。如果我们把字典程序抽象成一个可以提供“查字典”服务的对象的话,毫无疑问,如果想要向字典程序发送字符,必须首先知道字典程序能够接受什么,用什么方式把这个单词发送给字典等等。 所有的这些信息,都必须由操作系统托管才行(不可能每个应用程序里面都要记着字典这个程序能接受字符串不能接受图片,这样每个应用程序都要记下所有其他可能的应用程序的信息,这是一个平方级别的关系,需要开发人员开发一个程序的时候还要兼顾其他所有程序,这显然是不现实的)。用行话来说,必须要有一个统一管理的运行环境,来管理这些程序之间的互相通信问题。 我们上面说了,Smalltalk 的神在于一个统一的面向对象的运行时,使得所有的应用程序能互联互通。 可是所有平台上的 GUI 程序的演化进程都没有走这条路,而是只把外表给模仿走了;有的平台即使想做互联互通,也做得不彻底(比如微软的 OLE,COM 等等)。

是好东西,总会发光的。 但是要想让这个好东西被新的操作系统全盘采纳,要想让一个系统能够从底层到上层全部采用统一的运行环境,就要扔掉很多的历史包袱。甩掉这种历史包袱,对于任何操作系统都是不容易的。如果我们回到当年,一定会幻想,要是有个神人,能够不管市场也不管现有平台,从头打造一个没有任何历史包袱的干净整洁的 GUI 系统该多好。 历史就是这么戏剧,还真就安排了一个人,做成了这件事情,这个人,就是那个斯蒂夫乔布斯。

1985 年,乔布斯被苹果扫地出门,成立了 Next 公司, 一心想要做出质量上乘的 GUI 计算机系统。 历史给了乔布斯一个全部从头做的机会。这一次,乔老师和 Next 的开发人员意识到,光照搬 Smalltalk 的形是不行的,要连它的神也拿过来,重头设计进程间通信和 GUI 系统。 在内核层面,他们用了 Mach 这个为 BSD 设计的微内核。 这个操作系统内核就是为了替换已经过时的 UNIX 内核而设计的,其中的一个核心设计哲学就是重新设计进程间通信; 虽然现在基于微内核的操作系统已经不是什么潮流(为此 Linus 和 Tanenbaum 吵了一场著名的架),但在相比较于当时 UNIX 系统的内核(此时 Linux 还没出现的,UNIX 内核只有 BSD, Bell, SUN 等几套),Mach 算是一个高的起点。在这个内核上,Next 公司的工程师开始构建面向对象的基础系统。 这套系统在 Smalltalk 中已经有了蓝图,因此这些工程师以 Smalltalk 为蓝图,先设计了一套基于 C 的语言,也就是 Objective C,照搬了 Smalltalk 的经典的 [对象 消息: 参数] 语法。 (我个人不喜欢 Objective C 这个语言,Smalltalk 是一种纯面向对象的动态类型的语言,Next 公司当年完全有机会用 Smalltalk 语言的,如果用了 Smalltalk,现在的 Cocoa 框架还会更加漂亮,代码更加干净;用 Objective C 这个自创的语言,不知道是不是因为专利的考虑,反正 Objective C 这20年的所有创新,就是在慢慢的更像 Smalltalk 而已,Java 和 Ruby 这几年也是不断的从 Smalltalk 拿东西)。有了内核,有了语言,Next 构建了一个纯的面向对象的运行环境和类库(和 Java 和 .Net 的统一类库想法类似,只不过超前了十几年), 这套类库,在当时叫做 NextStep, 所以所有的类名前面都带有 NS 前缀,无比丑陋。可惜的是,当年这个超越时代的类库太阳春白雪了,话说 Smalltalk 超越了时代 20年,所以90 年代中期的时候, 程序员才想起来当年 Smalltalk 的好,出现了 Java Ruby 等等受 Smalltalk 启发的语言。 乔老师虽然落后了 Smalltalk 5 年,却领先也业界 5-10 年,所以在 1995 年的时候, Windows 95 卖疯了, 乔老师的 NextStep 却没动静,只能把这个类库重新打包当成 Web 类库卖卖,即 WebObjects。这倒是无心插柳,生意不错,因为当时的 Web 开发已经吃尽了没有一个统一的运行环境的苦头(这也是日后 Java 风行的原因)。 我们说,是金子总要发光的,但是前提是要 (1) Next 再等几年,等业界回过神来认识到它的好处,(2) 获得一个主流的操作系统支持,把底层全换成乔老师的东西。 乔老师也知道这两个条件,所以加快了和 SUN 合作的步伐,想要把这套系统放到 SUN 的工作站上。 但是 SUN 本身有很强的底层技术,那段时间又狂推 Java, 所以其实乔老师在 SUN 这条路上胜算不大,况且 SUN 自己内核技术很强,所以肯定要肢解 NextStep 把内核重写,如果不和 SUN 玩,一来Next 这家公司能够多撑 5 年都是问题,二来几乎每家做个人计算机的公司都倒戈微软了,其他做工作站的公司又都有自己很强的底层技术,不可能用乔老师的玩意儿的,所以看起来乔老师和他的阳春白雪好像前景不妙。 可是天无绝人之路,放眼看当年的市场,只有一家公司没有倒戈微软,又没有很强的底层技术,又和乔老师有一些渊源,历史就是这么戏剧,这家公司就是把乔老师扫地出门的苹果。

捧个钱场?

热评文章