2008年11月25日星期二

UNIX 與 Plan9 的比較

特別的硬體架構
所有的一切全是檔案
簡單就是美哲學
明智的安全性設計
九零年代的使用者界面
特別的硬體架構
標準的 Plan 9 會有一個專門的 CPU 伺服器、一個專門的檔案伺服器,
還有許多的終端機。檔案與 CPU 伺服器會用最快的網路連接。

所有的一切全是檔案
驅動程式、網路連線、環境變數,和許多其它的服務都是以檔案的形式來呈現在
獨立的檔案命名空間(file name space)。命名空間可依使用者的喜好調整。
使用者可以非常簡單的存取檔案伺服器,而且通訊協定使用單一的簡單協定。

簡單就是美哲學
Plan9 是為了程式設計師所設計的作業系統。它強調簡單就是美,這個概念到處
可見,所以 Plan9 強調 Simplicity 簡單設計而非到處可調(configurability),
優良設計而非相容性 (P9 與 UNIX 幾乎完全不相容),實用主義而非隨波逐流
(buzzword compliance)。

明智的安全性設計
P9 沒有 super-user 或是 root。與檔案伺服器的通訊協定非常簡單而沒有特殊
存取方式。所以密碼不用在網路上傳送。終端機直接與認證伺服器管理 challenge/
response 式的 session 。 (註:就是說,認證只在一次 session 中有效,可以想
成 one-time password 之類的東西。

九零年代的使用者界面
P9 直接假設系統都有一組三鍵滑鼠跟位元映射螢幕(bitmapped, 就是我們一般
在用的 CRT/LCD。 非 bitmap 的有 vector based...)。 天生支援 Unicode 系統
(事實上,P9 是第一個有 Unicode support 的 OS)。 字元式的界面 (如 vi, xterm,
rn) 已被慢慢放棄了。

2008年10月26日星期日

44本计算机科学类的经典书

1.The Art of Computer Programming
  Author: Donald.E.Knuth
  Web site: http://www-cs-faculty.stanford.edu/~knuth/taocp.html
  Book Info: 这部书被誉为20世纪最重要的20部著作之一,与Einstein的<<相对论>>并列,是计算机科学
领域的权威著作.全书共分7卷,目前已经出版了3卷,被誉为"计算机程序设计理论的荷马史诗","可与牛顿的
<<自然科学的数学原理>>媲美的巨著".作者数学方面的功底造就了本书严谨的风格,虽然本书不是用当今流
行的程序设计语言描述的,但这丝毫不损伤它"程序设计史诗"的地位.道理很简单,它内涵的设计思想是永远
不会过时的.The Art of Computer Programming 原计划要出七册,但目前只完成了三册.该书有日文,俄文,
西班牙文等许多国的版本.其中,中文版由国防大学出版社发行.
  Book Reviews:
  无数的读者都在谈论Knuth的书所带来的深远影响.科学家惊叹于分析逻辑之透彻严谨,而普通的编程人
员也已成功地将书中所列方案运用到他们的日常问题中.所有的人都非常赞赏Knuth在这套书中所表现的精确
与风趣,并为其明确性与涉及面之广而感到欣喜.
  我无法向你表达这套书在学习和创造性方面所带给我的兴奋与激动,我已经将它们带入了我的生活,就像
我的汽车,饭馆,工作,家庭……无所不在.
                             ----Charles Long
  无论你的背景怎样,如果你正在进行复杂的计算机编程,你就应该阅读本套书中的每本书,来补充你的专
业知识.
  当一个问题难以解决,而必须使用Knuth的这套书来解决时,总是一件令人愉快的事情.我发现在计算机方
面使用它们会有惊人的效果.
                             ----Jonathan Laventhol
  如果你认为你是一名真正优秀的程序员……读Knuth的<<计算机程序设计艺术>>,如果你能读懂整套书的
话,请给我发一份你的简历.
                             ----Bill Gates
  The Art of Computer Programming, Volume 1: Fundamental Algorithms (3rd Edition)
  Author: Donald.E.Knuth
  Publisher: Prentice Hall
  Amazon Reviews: Amazon.com
  Book Info: 卷1为基础运算法则,该书以基本的编程概念和技术为开始,然后讲述信息结构--计算机内信
息的表示法,数据元素间的结构关系以及处理它们的有效方法.主要应用于模拟,数字方法,符号计算,软件和
系统设计.许多简单和重要的运算法则和技术已添加到前一版本中,精确的初步计算部分已经修改,以适应当
前趋势.
  The Art of Computer Programming, Volume 2: Seminumerical Algorithms (3rd Edition)
  Author: Donald.E.Knuth
  Publisher: Prentice Hall
  Amazon Reviews: Amazon.com
  Book Info: 第2卷对半数值算法领域做了全面介绍,分"随机数"和"算术"两章.本卷总结了主要算法范例
及这些算法的基本理论,广泛剖析了计算机程序设计与数值分析间的相互联系.第3版中特别值得注意的是
Knuth对随机数生成程序的重新处理和对形式幂级数计算的讨论.
  The Art of Computer Programming, Volume 3: Sorting and Searching (2nd Edition)
  Author: Donald E.Knuth
  Publisher: Prentice Hall
  Amazon Reviews: Amazon.com
  Book Info: 卷3为分拣和搜索,这是本书的第1个修订版,它是对计算机分拣和搜索的一流技术的最全面
的研究,它扩展了卷1中数据结构的处理方法,将大小数据库以及内存和外部存储都包含在内.本书包括对计算
机方法仔细检查的选择方案,和其效率的大量分析.本书该版的独特之处在于优化了的分拣,以及对通用散列
法和排列法的新的理论论述.
  作者简介:
  Donald.E.Knuth(唐纳德.E.克努特,中文名高德纳)是算法和程序设计技术的先驱者,是计算机排版系统
TeX和METAFONT的发明者,他因这些成就和大量创造性的影响深远的著作(19部书和160篇论文)而誉满全球,在
计算机科学领域享有崇高的威望,是计算机科学界公认的大宗师.作为斯坦福大学计算机程序设计艺术的荣誉
退休教授,他当前正全神贯注于完成其关于计算机科学的史诗性的七卷集.这一伟大工程在1962年他还是加利
福尼亚理工学院的研究生时就开始了.Knuth教授获得了许多奖项和荣誉,包括美国计算机协会图灵奖(ACM
Turing Award),美国前总统卡特授予的科学金奖(Medal of Science),美国数学学会斯蒂尔奖(AMS Steele
Prize),以及1996年11月由于发明先进技术荣获的极受尊重的京都奖(KyotoPrize).现与其妻Jill生活于斯坦
福校园内.
  Donald.E.Knuth人生最辉煌的时刻在斯坦福大学计算机系渡过,获得了美国计算机协会图灵奖,成为本领
域内当之无愧的泰斗.

英文原版下载
http://www.shubulo.com/redirect.php?tid=34754

----------------------------------------------------------------
2.Introduction to Algorithms
  Author:Thomas H.Cormen ,Charles E.Leiserson ,Ronald L.Rivest ,Clifford Stein
  Amazon Reviews: Amazon.com
  Book Info: 简称为CLRS的<<算法导论>>,被称作"计算机算法的圣经".
  本书的主要作者来自麻省理工大学计算机,作者之一Ronald L.Rivest 由于其在公开秘钥密码算法RSA上
的贡献获得了图灵奖,目前是算法的标准教材,美国许多名校的计算机系都使用它,国内有些院校也将本书作
为算法课程的教材.另外许多专业人员也经常引用它.由于TAOCP只出版了3卷,CLRS比较起前者来则显得内容
更为全面,基本包含了所有的经典算法.本书程序全部由伪代码实现,这更增添了本书的通用性,使得利用各种
程序设计语言的程序员都可以作为参考.语言方面通俗,很适合作为算法教材和自学算法之用.国内的很多作
品名为数据结构,从本书中断章取义,把数据结构与算法混为一谈,搞得作者自己都迷迷糊糊.这也是我不十分
愿意向大家推荐国内作品的原因.你会发现现在基本上所有的数据结构与算法书籍都会将本书作为参考文献
之一,更可以说明一个问题,本书是作为读者进行算法学习的最佳选择.作为本书的补充内容,我愿意向大家推
荐下面的学习资料:你可以通过这个地址找到本书的所有练习答案:http://www.itu.dk/people/beetle/ .为
了更好的学习本书中的内容,最好的指导当然是来自作者本身讲述本书的课程,读者们可以通过
http://18.89.1.101/sma/5503fall2001/index5503fall2001.html获得课程的录像.

中文版
http://www.shubulo.com/thread-31351-1-1.html
习题及答案
http://www.shubulo.com/thread-33989-1-1.html

----------------------------------------------------------------
3.Data Structure & Algorithm Analysis in C (Second Edition)
  Author:Mark Allen Weiss
  Published:September 1996
  Web site:http://www.cs.fiu.edu/~weiss/
  Amazon Reviews: Amazon.com
  Book Info: 本书曾被评为20世纪顶尖的30部计算机著作之一,作者Mark Allen Weiss在数据结构和算法
分析方面卓有建树.他的数据结构和算法分析的著作尤其畅销,并受到广泛好评.已被世界500余所大学用作教
材.



----------------------------------------------------------------
4.Concrete Mathematics A Foundation for Computer Science(Second Edition)
中文版
http://www.shubulo.com/thread-33994-1-1.html
  Author:Donald.E.Knuth&Ronald L.Graham
  Web site: http://www-cs-faculty.stanford.edu/~knuth/gkp.html
  Amazon Reviews: Amazon.com
  Book Info: 很令人兴奋的就是这本书的主要作者正是泰斗Donald.E.Knuth以及他的同事Ronald
L.Graham.书稿是他们在1970年的时候在计算机系教授研究生本门课程的基础上整理出来的教材.内容上是
Knuth的巨著TAOCP第一部的扩展,有些比TAOCP中谈及地又深入了许多.重点放在高级计算机程序设计话题以
及算法分析上,涉及了计算机科学领域内几乎所有可能遇到的数学知识.具体数学是离散数学和连续数学的综
合,书中这点做得极为出色,介绍的内容涉及到书中许多经典问题的解答比目前广泛流传的解法更易懂.对于
提高大家的计算数学修养有很大帮助.之所以TAOCP有的时候读者们读不懂就是因为计算数学基础不是十分扎
实,但以我个人经验,若能对本书中内容有一个比较好的理解,会给你阅读如TAOCP这样的旷世巨著带来很大的
方便.



----------------------------------------------------------------
5.Discrete Mathematics and Its Applications,Fourth Edition
习题
http://www.shubulo.com/viewthread.php?tid=33130
  Author:Kenneth H.Rosen
  Amazon Reviews: Amazon.com
  Book Info: 本书的价值已经被全世界几百所大学所证实,作为离散数学领域的经典教材,全世界几乎所
有知名的院校都曾经使用本书作为教材.以我个人观点看来,这本书可以称之为离散数学百科.书中不但介绍
了离散数学的理论和方法,还有丰富的历史资料和相关学习网站资源.更为令人激动的便是这本书少有的将离
散数学理论与应用结合得如此的好.你可以看到离散数学理论在逻辑电路,程序设计,商业和互联网等诸多领
域的应用实例.本书的英文版(第五版)当中更增添了相当多的数学和计算机科学家的传记,是计算机科学历史
不可多得的参考资料.作为教材这本书配有相当数量的练习.每一章后面还有一组课题,把学生已经学到的计
算和离散数学的内容结合在一起进行训练.这本书也是我个人在学习离散数学时读的唯一的英文教材,实为一
本值得推荐的好书.



----------------------------------------------------------------
6.The C Programming Language 2nd Edition
英文版
http://www.shubulo.com/viewthread.php?tid=17067
习题及答案
http://www.shubulo.com/viewthread.php?tid=30825
  Author:Brian W.Kernighan and Dennis M.Ritchie
  Publisher: Prentice Hall
  Published: 1988.
  Amazon Reviews: Amazon.com
  Book Info: Brian W.Kernighan和Dennis M.Ritchie的传世之作.千千万万程序员和编程爱好者的圣经,
每一页都是价值连城的秘诀.不管你从哪一页信手翻起,最终你都会发现自己已经深陷其中而不能自拔.



----------------------------------------------------------------
7.The C++ Programming Language  Author:Bjarne Stroustrap
  Amazon Reviews: Amazon.com
  Book Info: 由C++之父亲手执笔的<>是每个程序员心目中不可动摇的
指南-----尽管官方标准还是ISO颁布的另一份文档,由ISO/IEC JTC1/SC22/WG21出版.TCPL是除了C++标准文
献之外最权威的C++参考手册.和大多数人的看法不大一样,我认为Bjarne的文字语言并不逊色于他所创建的
程序语言,至少我喜欢这种学院气息浓厚的作品.本书对C++语言的描述轮廓鲜明,直截了当.它从C++语言创建
者的角度来观察C++,这是任何别的作者和书籍做不到的----没有任何人比Bjarne自己更清楚该怎么来使用
C++.
  这是一本严肃的著作,以中,高级C++开发人员为目标读者.如果你是一名有经验的C++程序员,需要了解更
加本质的C++知识,本书正是为你而写.它不是那种让你看了会不断窃喜的小书,需要用心体会,反复咀嚼.在阅
读过程中,请特别留心Bjarne先生强调了什么,又对什么一语带过.我个人比较喜欢这本书的第四部分"使用
C++做设计",这样的内容在类似的程序设计语言书籍中很难看到----我甚至认为Bjarne应该将这部分独立出
来单独写一本书.



----------------------------------------------------------------
8.The Design and Evolution of C++
  Author: Bjarne Stroustrup
  Amazon Reviews: Amazon.com
  Book Info: D&E是一本关于C++语言设计原理,设计决策和设计哲学的专著.它清晰地回答了C++为什么会
成为今天这个样子而没有变成另外一种语言.作为C++语言的创建者,Bjarne淋漓尽致地展示了他独到而深刻
的见解.除了广受赞誉的语言特性外,Bjarne没有回避那些引起争议的甚至被拒绝的C++特性,他一一给出了逻
辑严密,令人信服的解释.内容涵盖C++的史前时代,带类的C,C++的设计规则,标准化,库,内存管理,多重继承,
模板等,对包括异常机制,运行时类型信息和名字空间在内的重要的新特性都分别进行了深入探讨.每一名C++
程序员都应该可以从Bjarne的阐释中加深对手中这门语言的认识.这本书知识浓缩,信息量极大,请不要错过
Bjarne每一句看似漫不经意的话.



----------------------------------------------------------------
9.Accelerated C++: Practical Programming by Example
  Author: Andrew Koenig, Barbara E.Moo
  Publisher: Addison-Wesley Professional
  Published: January 15, 2000
  Amazon Reviews: Amazon.com
  Book Info: 和市面上大多数C++教程不同,本书不是从"C++中的C"开始讲解,而是始于地道的C++特性.从
一开始就使用标准库来写程序,随着讲述的逐渐深入,又一一解释这些标准库组件所依赖的基础概念.另外,和
其他C++教材不同的是,这本书以实例拉动语言和标准库的讲解,对后两者的讲解是为了给实例程序提供支持,
而不是像绝大多数C++教材那样,例子只是用作演示语言特性和标准库用法的辅助工具.
  作者在C++领域的编程实践,教育培训以及技术写作方面都是世界一流水准.我喜欢这种大量使用标准库
和C++语言原生特性的清新的写作风格.在这本教材面前,几乎迄今为止的所有C++教材都黯然失色或显得过时
.尽管这本教材也许对于国内的高校教育来说有些前卫,不过我仍然极力向我的同行们推荐.顺带一提,在
Bjarne和我最近的一封通信里,他这样评价本书:对于有经验的程序员学习C++而言,这本书可能是世界上最好
的一本.



----------------------------------------------------------------
10.C++ Gotchas: Avoiding Common Problems in Coding and Design  Author: Stephen C.Dewhurst
  Publisher: Addison-Wesley Professional; 1st edition (November 26, 2002)
  Amazon Reviews: Amazon.com
  Book Info: Stephen的理论素养和实践经验注定这是一本值得一读的好书.Stephen曾经是贝尔实验室中
第一批C++使用者.他已经使用C++成功解决了包括编译器,证券交易,电子商务以及嵌入式系统等领域中的问
题.本书汇集了作者来自开发一线的99条编程真知灼见,洞悉它们,你可以避免几乎所有常见的C++设计和编程
问题.
  我甚至认为,对于C++编程菜鸟而言,阅读这本书会比阅读Scott和Herb的书更能轻松而立竿见影地获得更
大的提高.我个人很喜欢这本书的写作风格----Stephen的许多观点看似极端却无可辩驳.当然了,这种自信(
以及冷幽默)来自于作者深厚的技术素养,而非自大的偏执.

11.C++ Primer 3rd
  Author: Stanley B.Lippman
  Amazon Reviews: Amazon.com
  Book Info: 这本书的名字多少有点让人误解.尽管作者声称这本书是为C++新手而写,但无论是它的厚度
还是讲解的深度都暴露了似乎并非如此.也许说它是一本"从入门到精通"的C++教程会更合适一些.我个人认
为它并不适合完全不懂C++的初学者----在阅读这本书之前,你至少应该先有那么一点C或C++的背景知识,或
者至少要具有一些其他语言的编程经验.
  尽管这本书省略了一些高级C++特性的讨论,但仍然可以称得上是迄今为止最全面的C++学习教程.事实上
,如果一名C++初学者能够扎扎实实地读完本书并对照<>完成全部习题的话,他的
水平肯定可以进入职业C++程序员的行列.我个人认为,即使你已经拥有了TCPL,这本书依然有拥有的价值,因
为在许多方面它比TCPL来得更详细,更易懂.



----------------------------------------------------------------
12.Essential C++
  Author: Stanley B.Lippman
  Amazon Reviews: Amazon.com
  Book Info: 可以不太严格地认为这本书是<>的精简版.本书一一讲述了C++中最具代表性
的主题,包括过程式编程,泛型编程,基于对象编程,面向对象编程,模板编程以及异常处理等.Stanley将门槛
调低到"具有其他语言程序设计经验"的C++新手所能接受的最基本的层次,使他们能够迅速开始使用C++编程
而又免于阅读<>那样的大部头.它以实例引导学习,力图使读者在最短的时间内把握C++的精粹.
  也许换一个人来概述C++编程范型(paradigm)的方方面面需要好几百页才能说清楚,但这本小书不可思议
地做到了这一点.我个人非常喜欢这种满是技术,简明扼要并且"有话好好说"的书.这本书同样具有一个明显
的风格:所有程序例子全部采用标准库组件,让人耳目一新.



----------------------------------------------------------------
13.Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition)
  More Effective C++: 35 New Ways to Improve Your Programs and Designs
  Author: Scott Meyers
  Publisher:Prentice Hall
  Amazon Reviews: Amazon.com
  Amazon.com
  Book Info: 先养成良好的C++设计习惯,这是Scott Meyers的<>和<C++>>带给我们的无穷好处,这两本书是真正的经典,作者对C++的纯熟,使得语言的风格读起来简直是如饴甘
甜,就像他站在你对面讲课.如果你已经深刻地理解了<>和<>,那你可
以发现,你在众人中已经是鸡群之鹤.
  如果说<>主要讨论C++中一些相对基础的概念和技巧的话,那么<C++>>则着重探讨了包括异常处理在内的一系列高级技术.与前者相比,后者具有两大主要区别:其一,它包含
很多时新的标准C++的内容;第二,它讨论的主题倾向于"战略化"而非"战术化",并且讨论得更深入,更彻底.尤
其是对虚析构函数,智能指针,引用计数以及代理类(proxy classe)等技术和模式论述的深入程度,让人很难
想象是出现于这样的一本小书之中.



----------------------------------------------------------------
14.Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions
   More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions
  Author: Herb Sutter
  Book Info: 你自认为是一名C++语言专家吗?读一读ISO C++标准委员会秘书长的这两本书再回答.在这
两本书中,Herb采用了"问答"的方式指导你学习C++语言特性.对于每一个专题,Herb首先合理地设想出你的疑
问和困惑,接着又猜测出你十有八九是错误的解答,然后给你以指点并提出最佳解决方案,最后还归纳出解决
类似问题的普适性原则.
  这两本书是典型的深究C++语言细节的著作,很薄,但内容密集,远远超过Scott的那两本书,读起来很费脑
筋----我个人认为它们要比Scott的书难懂得多.若要研习这薄薄的两本书所包含的知识,至少需要花费数月
的时间!(在Scott的荐序中,他坦陈不止一次陷入GotW问题的陷阱,你应该知道这意味着什么)对于语言细节的
深究有什么好处呢?尽管在大多数情况下,我们不必关心C++代码幕后的动作,然而当我们不得不关心时,这两
本书可以为我们提供很好的线索,因为它们揭示了C++语言中微妙而又至关重要的东西.



----------------------------------------------------------------
15.Modern C++ Design: Generic Programming and Design Patterns Applied
  Author: Andrei Alexandrescu
  Publisher: Prentice Hall
  Amazon Reviews: Amazon.com
  Book Info: 你自认为是C++模板编程高手吗?请看过这本书再回答.这是一本出自天才之手令人敬畏的杰
作.泛型模式,无限延伸你的视野,足以挑战任何一名C++程序员的思维极限.
  这本书共分为两大部分,第一部分讨论了Loki程序库采用的基础技术以及一些高级语言特性,包括基于策
略的类设计,模板局部特化,编译期断言,Typelist以及小型对象分配技术等.第二部分则着重介绍了Loki中的
重要组件和泛型模式技术,包括泛化仿函数(Generalization Functor),单件(Singleton),智能指针,对象工
厂(Object Factory),抽象工厂(Abstract Factory),访问者(Visitor)以及多方法(Multimethods)等.每一种
技术都让人大开眼界,叹为观止.



----------------------------------------------------------------------------------
16.C++ Templates: The Complete Guide
  Author: David Vandevoorde, Nicolai M.Josuttis
  Amazon Reviews: Amazon.com
  Book Info: 有一种老套的赞美一本书的手法,大致是"没有看过这本书,你就怎么怎么地",这里面往往夸
张的成分居多.不过,倘若说"没有看过<>,你就不可能精通C++模板编
程",那么这个论断对于世界上绝大多数C++程序员来说是成立的.这本书填补了C++模板书籍领域由来已久的
空白.此前,上有<>这样的专注于模板高级编程技术和泛型模式的著作,下有<Standard Library>>这样的针对特定模板框架和组件的使用指南.然而,假如对模板机制缺乏深入的理解,你
就很难"上下"自如.鉴于此,我向每一位渴望透彻理解C++模板技术的朋友推荐这本书.



----------------------------------------------------------------
17.The C++ Standard Library: A Tutorial and Reference
  Author: Nicolai M. Josuttis
  Publisher: Addison-Wesley Professional; 1st edition (August 12, 1999)
  Amazon Reviews:
[http://www.amazon.com/exec/obidos/tg/detail/-/0201379260/002-5778374-2660009?v=glance]Amazon.
com[/URL]
  Book Info: 这是一本百科全书式的C++标准库著作,是一本需要一再查阅的参考大全.它在完备性,细致
性以及精确性方面都是无与伦比的.本书详细介绍了每一标准库组件的规格和用法,内容涵盖包括流和本地化
在内的整个标准库而不仅仅是STL.正如本书副标题所示,它首先适合作为教程阅读,尔后又可用作参考手册.
  浅显易懂的写作风格使得这本书非常易读.如果你希望学习标准库的用法并尽可能地发挥其潜能,那你必
须拥有这本书.正如网络上所言,这本书不仅仅应该摆在你的书橱中,更应该放到你的电脑桌上.我向每一位职
业C++程序员强烈推荐.
----------------------------------------------------------------
18.Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition)  Author: Scott Meyers
  Publisher: Addison-Wesley Professional; 2 edition (September 2, 1997)
  Amazon Reviews: Amazon.com
  Book Info:
  Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library
  Author: Scott Meyers
  Publisher: Addison-Wesley Professional; 1st edition (June 6, 2001)
  Amazon Reviews: Amazon.com
  Book Info: 读完Scott 的<>和<>的中译本之后,我一直期待这
本书的中文版.我从潘爱民先生的个人主页上了解到,他和他的合作伙伴似乎早已完成了这本书的翻译工作,
可惜至今市面上仍不得见.幸运的是,我们可以看到它的原版.
本书是使用STL的程序员必读之作.在这本书中,Scott向我们讲述STL容器和算法的工作机制以及如何以最佳
方式使用它们.和Scott的其他作品一样,这本书的写作风格清晰,精确,具有极佳的可读性.看过这本书以后,
我想你也许会和我以及其他C++程序员一样产生这样的想法:Scott什么时候会写出一本"More Effective
STL"?

----------------------------------------------------------------
19.Thinking in C++, Volume 1: Introduction to Standard C++ (2nd Edition)  Author: Bruce Eckel
  Publisher: Prentice Hall; 2nd edition (April 15, 2000)
  Amazon Reviews: Amazon.com
  Book Info: <>的第1版于1996年荣获"软件研发"杂志评选的图书震撼大奖.最新推出
的第2版对内容进行了大幅改写和调整,以反映C++标准化带来的影响以及近几年面向对象领域最新研究和实
践成果."输入输入流","多重继承","异常处理"和"运行时类型识别"等高级主题连同C++标准化以后增加的一
些内容则被放入第二卷中.Bruce是一名经验丰富的C++讲师和顾问,其培训和写作经验都是世界一流水准,他
的作品比那些"玩票"的技术人员写的东西更能吸引读者.事实上,在同类图书中,对于大多数读者而言,这本书
的可读性要超过TCPL和<>.
  Thinking in C++, Volume 2: Practical Programming (Second Edition)
  Author: Bruce Eckel
  Publisher: Prentice Hall; 2nd edition (November 1, 2003)
  Amazon Reviews: Amazon.com
  Book Info:



----------------------------------------------------------------
20. Ruminations on C++: A Decade of Programming Insight and Experience
  Author: Andrew Koenig, Barbara E. Moo, Barbara E. (Editor) Moo
  Publisher: Addison-Wesley Professional; 1st edition (August 7, 1996)
  Amazon Reviews: Amazon.com
  Book Info: Andrew是世界上屈指可数的C++专家.这是一本关于C++编程思想和程序设计技术而非语言细
节的著作.如果你已经具有一定的基础,这本书将教你在进行C++编程时应该怎样思考,应该如何表达解决方案
.整本书技术表达透彻,文字通俗易懂.Bjarne这样评价这本书:本书遍布"C++是什么,C++能够做什么"的真知
灼见.



----------------------------------------------------------------
21.Design Patterns: Elements of Reusable Object-Oriented software  Author: Erich Gamma
  Publisher: Addison Wesley Longman; (1998
  Amazon Reviews: Amazon.com
  Book Info: 设计可复用的面向对象的软件,你需要掌握设计模式.本书并非专为C++程序员而写,但它采
用了C++(以及Smalltalk)作为主要示例语言,C++程序员尤其易于从中受益.四位作者都是国际公认的面向对
象软件领域专家,他们将面向对象软件的设计经验作为设计模式详细记录下来.这本书影响是如此深远,以至
于四位作者以及本书都被昵称为GoF(Gang of Four).本书学院气息浓厚,行文风格严谨简洁,虽然它不如某些
讲解模式的书籍易读,但真正要精准地理解设计模式,本书是终极权威.学习设计模式,这本书需要一而再,再
而三的咀嚼.顺带一句:请将设计模式化作开拓思维的钥匙,切莫成为封闭思维的枷锁.



----------------------------------------------------------------
22.Efficient C++: Performance Programming Techniques
  Author: Dov Bulka, David Mayhew
  Publisher: Prentice Hall
  Amazon Reviews: Amazon.com
  Book Info: 这本超薄小书聚焦于高性能C++应用程序开发.两位作者都是IBM软件专家,都工作于对性能
要求极高的系统构建领域,本书是他们的经验之谈.也有人不喜欢这本书,因为它花了不少的篇幅讲述和C++无
关的东西,我却恰恰因为这一点而对这本书产生好感,正是这些东西让我开阔了眼界.



----------------------------------------------------------------------------------
23.Inside the C++ Object Model
  Author: Stanley B.Lippman
  Publisher: Addison-Wesley Pub Co
  Published: May 3, 1996
  Amazon Reviews: Amazon.com
  Book Info: 从编译器的角度观察C++可以使你知其然并知其所以然.本书探讨了大量的C++面向对象程序
设计的底层运作机制,包括构造函数,函数,临时对象,继承,虚拟,模板的实例化,异常处理,运行期类型识别等
,另外还介绍了一些在实现C++对象模型过程中做出的权衡折衷.喜欢刨根问底的C++程序员可以从中了解了无
数的编译器解释源代码的细节,以及记忆体分配的细节..24.The Art of Assembly Language
  Author: Randall Hyde
  Amazon Reviews: Amazon.com
  Book Info: 本书以X86系列微机为背景,从简单的Hello程序开始,系统而详细地阐述了X86微机汇编语言
编程的各种基础知识和编程技巧,内容涉及到数据表示,存储器管理,各种数据类型,过程,与汇编语言相关的
体系结构,控制结构,文件,宏指令,位处理指令,字符串指令,MMX指令,类和对象,以及混合语言编程等,尤其是
在高级汇编语言(HLA)方面,该书给予了细致深入的讲解.对于有意学习X86汇编语言编程的程序员来说,这是
一本难得的好书.
  本书的作者Randall Hyde在大学中教授汇编语言十多年,并且开发了好几个商用软件,具有丰富的汇编语
言开发经验.该书的英文电子版受到了成千上万的网站和高级程序员的高度评价,已经成为了高级汇编语言编
程方面的一本经典之作.虽然该书的出版时间不长,但在Amazon上为该书作出评价的人很多,而且几乎所有的
人都给予5星的评价,可见其内容之好.可以相信,随着时间的推移,它在程序员中的影响会越来越大.
----------------------------------------------------------------
25.The Design and Implementation of the 4.4BSD Operating System
  Auther:
  Marshall Kirk McKusick, Consultant
  Keith Bostic, Berkeley Software Design, Inc.
  Michael J.Karels, Berkeley Software Design, Inc.
  John S.Quarterman, Texas Internet Consulting
  Publisher: Addison-Wesley Publishing Company
  Published: 04/30/1996
  Book Info: 是第一本完整描述伯克利最新版本4.4BSD设计和实现的权威性著作.书中介绍了4.4BSD的内
部结构和实现4.4BSD的系统功能中所用的概念,数据结构和算法.书中着重对4.4BSD 和 AT&T System V UNIX
版本的不同处作了较详细的描述,并对其设计思想及背景作了清晰的阐述.该书对研究,开发和使用 UNIX 系
统,特别是4.4BSD UNIX 实现中的一些新技术,新特点.有很大的参考价值.



----------------------------------------------------------------
26.John Lions:Lions’Commentary on UNIX 6th Edition with Source Code
  Author: John Lions
  Amazon Reviews: Amazon.com
  Book Info: 在20世纪70年代和80年代这一时期,莱昂的几册<<源代码分析>>,曾是人们争相传看的UNIX
系统的"地下出版物".我们今天来审视这一著作,尽管其中的代码已属过时,但其注释者所作的大部分注释,依
然完美如初.要想学习操作系统原理,就必须阅读和理解源代码.莱昂的工作,使我们中间的大多数人都能达到
这一步.
  Book Reviews:
  本书中的材料确定是有点过时了,其内容不包括图形,网络以及1975年后出现的新事物.即使在1979年的
编译中也不再使用的线性搜索,基本数据结构和C代码还保留在本书的源代码中,而该代码面向的计算机非常
简单,只比存储器稍稍多一些.从中你会发现有很多粗糙之处.但是在代码中你也可以观察到其基本结构,该结
构沿用了很长时间,而且能够包容在计算环境中发生的巨大变化.在莱昂的分析中,你可以觉察到新鲜的,经常
提出问题的立场,其中的很多词语和思想都很适宜于教育和学习.莱昂非常清楚地赞赏他阅读的UNIX源代码,
但又立即指出其不足之处.他帮助他的学生理解蕴含在源代码中的很多思想和主题,也坦率地说明他对该代码
某些部分感到的困惑之处.此处重印的文献已经教育了一代人,它是计算机界中复印数量最多的一本书稿.将
此公开记录在案是件大好事.
                             ----丹尼斯.M .里奇
  最后我还想提及的是:现在,得到最广泛传播的一份地下计算机科学文献已经可以自由地使用了.我对
1977年中的那一天仍然是记忆犹新,那时我接到邮寄来的此书的第一份草稿,开始时我对此书并无很多期望,
但是最后却是逐字逐句进行了仔细阅读.20年之后,此书依旧是对一个实际操作系统工作的最好分析说明.
                             ----肯?汤姆森
  (汤姆森和里奇因为开发和实现UNIX操作系统而共同获得1983年ACM美国计算机协会图灵奖).



----------------------------------------------------------------
27.Operating Systems: Design and Implementation (Second Edition)
  Author: Andrew S.Tanenbaum, Albert S.Woodhull
  Publisher: Prentice Hall; 2nd edition (January 15, 1997)
  Amazon Reviews: Amazon.com
  Book Info: 本书是一本理论结合实践的杰出教材.作者不仅介绍了所有基本原理,如:进程,进程间通信,
输入/输出,虚拟存储,文件系统及系统安全,也介绍了线程概念,同时又详尽地讨论了MINIX系统(一种UNIX兼
容系统),使学生不仅能学到原理,还能通过使用MINIX来了解如何将这些原理应用到真实的操作系统中.作者
更新了所有原理性材料以反映该领域的新进展.基于POSIX的MINIX系统经修订后可运行在基于奔腾(Pentium)
的计算机上.MINIX代码可用于Ethernet和TCP/IP联网环境.每本书均附光盘,内含MINIX全部源码和可运行各
种计算机上的两个模拟程序.每章后均附思考题.



----------------------------------------------------------------
28.Modern Operating Systems (2nd Edition)
  Author: Andrew Tanenbaum
  Publisher: Prentice Hall
  Amazon Reviews: Amazon.com
  Book Info: 对于软件开发专家以及计算机专业的学生来说,<<现代操作系统>>给出了操作系统设计一个
概念上的全面见解,包括Unix/Linux和Windows 2000的详细个案研究.本书共分两部分,第一部分详尽讲述了
传统操作系统知识,包括进程,存储器管理,文件系统,I/O设备管理,死锁等内容;第二部分主要介绍了分布式
操作系统,包括层次协议,远程过程调用,互斥操作,分布式文件系统等专题.为加深概念的理解,本书还详细介
绍了四个操作系统,包括两个传统的系统UNIX和MS-DOS;两个分布式系统Amoeba和Mach.此外还简要介绍了
NFS,AFS,ISIS等其他几个系统.本书体系完整,内容丰富,叙述清晰,是大学计算机及相关专业学生不可多得的
教科书,对于从事计算机管理,开发,系统分析等职业的专业人员也是优秀的参考书.



----------------------------------------------------------------
29.Operating System Concepts
  Author: Abraham Silberschatz, Greg Gagne, Peter Baer Galvin
  Amazon Reviews: Amazon.com
  Book Info: 本书是计算机类专业操作系统课程的一本经典教材,自第一版问世以来,经历了近20年的锤
炼,被认为是该课程教材的一本"圣经".它对操作系统的概念和基本原理给出了清晰的阐述.本书所涉及的基
本概念和算法均基于当前商用操作系统,并在非特定操作系统的通用环境中展开讲解.书中介绍了大量与流行
操作系统相关的实现技术,包括Solaris2,Linux,Windows NT,Windows 2000,OS/2和Apple Macintosh操作系
统.此版包括了线程,Windows 2000的新章节,并新增了客户/服务器
模型和网络文件系统,嵌入式操作系统,实时操作系统,分布式操作系统等.



----------------------------------------------------------------
30.Running MS-DOS
  Author: Van Wolverton
  Published: 18 November 1993
  Book Info: MS-DOS 上的清晰工作!
  经过10年无数次竞争,<>仍是被其它 MS-DOS 奉为标准的书.Van Wolverton 的实际的
写作风格,上百张屏幕演示,使得<>成为任何时候的DOS指南畅销书.再没有哪个计算机书从
读者和评论家那里获得过这么多的赞扬.
  这本新的,10 周年纪念版本,包括关于 MS-DOS 6.2 最新版本的重要的信息.如果您仅仅只是买了一台
PC 机,或者只是升级到了一个新版本,<>应当成为您的第一个信息源.<>
实际上是由3本书合成的,包括:
  MS-DOS 介绍,以及如何同您的计算机硬件相协调
  一个关于了解和使用 MS-DOS 的完整制导
  一个命令手册,里面有定义,例子和表格,帮您快速寻找信息!

----------------------------------------------------------------
31.Advanced Programming in the UNIX? Environment
  Author: Richard W.Stevens, Stephen A.Rago
  Publisher: Addison-Wesley Professional
  Amazon Reviews: Amazon.com
  Book Info: 与大多数其他操作系统类似,Unix对运行其上的程序提供了大量服务,此外,本书与其他Unix
编程书籍不同的是,本书除了讲述Unix系统的编程接口----即系统调用接口和由标准C函数库提供的大量函数
之外,还通过许多例子和基本原理对Unix编程环境做了更深入的解释和剖析,如怎样创建数据库,页面描述语
言的打印机驱动程序,现代拨号程序以及代理进程,处理机间通信,伪终端程序等.本书作者是Unix研究领域的
专家,而本书更被誉为是该领域的圣经宝典,相信每一位读者都会在学习本书的过程中体会到它的价值所在.



----------------------------------------------------------------
32.Unix Network Programming
 
  Unix Network Programming, Volume.1: The Sockets Networking API, Third Edition
  Author: W.Richard Stevens, Bill Fenner, Andrew M.Rudoff, Richard W.Stevens
  Publisher: Addison-Wesley Professional
  Amazon Reviews: Amazon.com
  Book Info: 这是一本利用应用编程接口(API)编写法对计算机网络进行通信的网络编程的教程.所用的
API有两类: 基于BerkeleyUNIX操作系统的"Berkeley"套接字和基于AT&T开发的X Open传输接口XTI.本书分
四大部分:Ⅰ.引论和TCP/IP;Ⅱ.基本套接字(Sockets);Ⅲ.高级套接字;Ⅳ.XTI X/Open传输接口.四个附录:
A.IPv4,IPv6,ICMPv4和ICMPv6;B.虚拟网络;C.调试技术;D.一些关键源代码.全书内容全面,实用性强,是一本
极好的参考书.
  UNIX Network Programming, Volume 2: Interprocess Communications (2nd Edition)
  Author: W.Richard Stevens
  Publisher: Addison-Wesley Professional
  Amazon Reviews: Amazon.com
  Book Info: 一种良好的进程间通信(IPC)形式是复杂精致的UNIX程序性能之关键.本书全面深入地介绍
了各种进程间通信形式,包括消息传递,同步,共享内存及远程调用(RPC).作者从介绍IPC的基础及其所要解决
的问题开始,逐步引导读者学习如何使System V IPC和新的Posix标准两者都达到极至.书中Pthread的内容有
较大的扩充,所附的许多例子反映多个线程而不是多个进程.读者通过本书将能掌握各种现行的IPC技术,其中
有:管道和FIFO;Posix和System V消息队列;互斥锁和条件变量;读写锁;记录上锁;Posix和System V信号灯
;Posix和System V共享内存;Solaris门和Sun RPC;IPC技术的性能测量.本书内容详尽且具有权威性,几乎每
章都有精选的习题,是计算机和网络专业高年级本科生和研究生的首选教材,本书也可作为网络研究和开发人
员的自学教材和参考书.



----------------------------------------------------------------
33.TCP/IP Illustrated
 
  Web site: http://www.kohala.com/start/
  TCP/IP Illustrated,Volume 1:The Protocols
  Author: W.Richard Stevens
  Publisher: Addison-Wesley
  Amazon Reviews: Amazon.com
  Book Info: <>是一本完整而详细的TCP/IP协议指南.描述了属于每一层的各个
协议以及它们如何在不同操作系统中运行.作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作
系统和TCP/IP实现之间传输的不同分组.对tcpdump输出的研究可以帮助理解不同协议如何工作.本书适合作
为计算机专业学生学习网络的教材和教师参考书.也适用于研究网络的技术人员.
  TCP/IP Illustrated,Volume 2:The Implementation
  Author: Gary R.Wright, W.Richard Stevens
  Publisher: Addison-Wesley
  Amazon Reviews: Amazon.com
  Book Info: 本书完整而详细地介绍了TCP/IP协议是如何实现的.书中给出了约500个图例,15,000行实际
操作的C代码,采用举例教学的方法帮助你掌握TCP/IP实现.本书不仅说明了插口API和协议族的关系以及主机
实现与路由器实现的差别.还介绍了4.4BSD-Lite版的新的特点,如多播,长肥管道支持,窗口缩放,时间戳选项
以及其他主题等等.读者阅读本书时,应当具备卷1中阐述的关于TCP/IP的基本知识.本书适用于希望理解
TCP/TP协议如何实现的人,包括编写网络应用程序的程序员以及利用TCP/IP维护计算机网络的系统管理员.
  TCP/IP Illstrated,Volume 3:TCP for Transactions,HTTP,NNTP,and the UNIX Domain Protocols
  Author: W.Richard Stevens
  Publisher: Addison-Wesley
  Amazon Reviews: Amazon.com
  Book Info: 本书是<>的延续.主要内容包括:TCP事务协议,即T/TCP,这是对TCP的扩展
,使客户-服务器事务更快,更高效和更可靠;TCP/IP应用,主要是HTTP和NNTP;UNIX域协议,这些协议提供了进
程之间通信的一种手段.当客户与服务器进程在同一台主机上时,UNIX域协议通常要比TCP/IP快一倍.本书同
样采用了大量的实例和实现细节,并参考引用了卷2中的大量源程序.本书适用于希望理解TCP/IP如何工作的
人,包括编写网络应用程序的程序员以及利用TCP/IP维护计算机网络的系统管理员.
  作者简介:
  Gary R.Wright 研究TCP/IP多年.他是Connix公司的董事长,这个公司的基地在康涅狄格州,它提供
Internet接入和咨询服务.W.Richard Stevens(1951-1999)是一位非常受人尊敬的专家,除了<>
三卷本外,他还有其他两部最为畅销的作品;<>和<>(两卷本).

----------------------------------------------------------------
34.Routing TCP/IP
 
  CCIE Professional Development:Routing TCP/IP Volume 1
  Author: Jeff Doyle
  Publisher: Cisco Press; 1st edition (July 1, 1998)
  Amazon Reviews: Amazon.com
  Book Info: 本书是第一本详细而又完整地介绍互联网络内部网关路由选择协议(IGRP)的专业书籍,堪称
有关IGRP方面不可多得的经典之作.本书共分三个部分.第一部分主要介绍了网络和路由选择的基本知识,对
TCP/IP和静态,动态路由选择技术作了一个整体的回顾.第二部分是本书的精华,这一部分详细深入地讲述了
各种常用的内部网关路由选择协议,如静态路由,RIP,RIPv2,IGRP,EIGRP,OSPF,ISIS等,每一章除了对该协议
的实现机制和参数详尽阐述,使读者对协议的实现原理有一个清晰的理解外,还通过在实际网络环境中的实例
,详细地论述了该协议在Cisco路由器上的配置和故障处理方法,使读者获取大量解决实际问题的专业技能.第
三部分介绍了如缺省路由,路由过滤等多种有效的路由控制工具,用来创建和管理多个IP路由选择协议的协调
工作.本书不仅适合那些需要准备通过CCIE考试的考生,而且也适合任何需要完整理解TCP/IP内部路由选择协
议的网络设计和工程人员阅读.本书中对协议细节的讲解和对网络实例的探讨相信会让读者获益匪浅.
  CCIE Professional Development Routing TCP/IP Volume 2
  Author: Jeff Doyle, Jennifer DeHaven Carroll
  Publisher: Cisco Press; 1st edition (April 11, 2001)
  Amazon Reviews: Amazon.com
  Book Info: 本书深入系统地阐述了TCP/IP路由技术,内容包括几种重要的网络协议,如外部网关协议
(EGP),边界网关协议(BGP4),以及相应的高级IP路由技术与应用――网络地址转换,IP组播路由技术,IPv6技
术,路由器管理等.本书共分9个章节,首先介绍并讨论了主题内容的基本原理,接着是设计用来展示真实网络
环境中相关概念的一系列配置范例,最后提供给读者经实践验证过的故障排除方法以解决网络可能会出现的
问题.重点介绍了自治系统之间的路由选择策略以及诸如组播和IPv6等更具挑战性的路由选择和实施技术.
----------------------------------------------------------------
35.Data and Computer Communications,Seventh Edition
  Author: William Stallings
  Amazon Reviews: Amazon.com
  Book Info: 本书是著名计算机专业作家 William Stallings 的经典著作之一,内容涉及最基本的数据
通信原理,各种类型的计算机网络及多种网络协议和应用.这一版对原有内容做了彻底的修订和重组,使新版
对通信各专题的阐述更全面,更清晰.同时,新版加强了无线通信和组网,吉比特以太网,区分服务,MPLS和
TCP/IP实现细节等内容.此外,本书还包括词汇表,参考文献,缩写词对照表.每章都附有习题和建议,以便读者
进一步阅读.



----------------------------------------------------------------
36.Programming Pearls, 2nd Edition
  Author: Jon Bentley
  Publisher: Addison-Wesley Professional; 2 edition (September 27, 1999)
  Amazon Reviews: Amazon.com
  Book Info: 如果让程序员们列出他们最喜欢的书籍,Jon Bentley的<<编程珠玑>>通常可以位于经典之
列.如同珍珠来自于曾经折磨牡蛎的沙粒,程序设计的珍珠也来自曾经折磨程序员的实际问题.Bentley的珍珠
建立在坚实的工程学基础上,在洞察力和创造力的王国中为那些恼人的问题提供了独特而巧妙的解决方案.通
过一些精心设计的有趣而且颇具指导意义的程序,本书对众多实用程序设计技巧及基本设计原则作了清晰而
机智的描述.因此,<<编程珠玑>>得到各个层次程序员的青睐并不让人感觉意外.
  为了反映当今的程序设计方法和环境,Bentley在本书中彻底更新了第一版里的大多数素材.此外,他还新
增加了以下三个方面的内容:1.测试,调试和计时 2.集合表示 3.字符中问题
  对原来的所有程序都重新进行了改写,并生成了等量的新代码.您可以从本书网站
([urwww.programmingpearls.com)[/url]获取所有程序的C或C++实现.
  Book Reviews:
  <<编程珠玑>>第一版是我职业生涯早期阅读过的最有影响力的书籍之一,第一次从该书中学到的许多观
点很久以后仍然使我受益匪浅.Jon在第二版中对素材进行了大量更新,这些新例子的新鲜程度给我留下了深
刻的印象.
                             ----Steve McConnell <Complete>>等多部畅销书作者



----------------------------------------------------------------
37.The Mythical Man-Month: Essays on Software Engineering, 20th Anniversary Edition
  Author: Frederick P, Brooks,Jr.
  Publisher: Addison-Wesley Professional; 1st edition (August 2, 1995)
  Amazon Reviews: Amazon.com
  Book Info: IBM大型电脑之父 Fred Brooks 二十余年开发经验的汇集,远谋深虑,字字珠玑.技术之巧与
人文之美的完美结合.本书自第一版以来,畅销二十余年不衰,是软件领域绝无仅有的必读经典.
  作者简介:
  Frederick P 曾荣获美国计算机领域最具声望的图灵奖(A.M.Turing Award)桂冠.美国计算机协会(ACM)
称赞他"对计算机体系结构,操作系统和软件工程做出了里程碑式的贡献."
  Brooks 博士是北卡罗莱纳大学 Kenan-Flagler 商学院的计算机科学教授.他被认为是"IBM 360系统之
父",曾担任了360系统的项目经理,以及360操作系统项目设计阶段的经理.凭借在上述项目中的杰出贡献
,Brooks博士以及Bob Evans和Erich Bloch在1985年荣获了美国国家技术奖(National Medal of
Technology).Brooks博士早期曾担任IBM 公司Stretch和Harvest计算机的体系结构设计师.
  Brooks 博士创立了北卡罗莱纳大学的计算机科学系,并在1964~1984年期间担任系主任.他还曾任职于
美国国家科技局和国防科学技术委员会.他目前的教学和研究方向是计算机体系结构,分子模型绘图和虚拟环
境设计.



----------------------------------------------------------------
38.The Pragmatic Programmer
  Author: Andrew Hunt,David Thomas
  Publisher: Addison Wesley
  Published: November 24, 1999
  Amazon Reviews: Amazon.com
  Book Info: 本书直击编程阵地,穿过了日益增长的现代软件开发的规范和学术,对核心过程进行了审视
----该过程采取了供需结合的工作方式和令人欣喜的可维护代码.本书包含的内容从个人责任和职业发展到
保持代码的灵活性,使之易于改编和重用.
  本书由各个相对独立的章节组成,其间不乏好玩的轶事,详细的实例和有趣的对话,描述了软件开发各个
方面的最好实践和主要缺陷.无论你是一个新入门的编码者,一个有经验的程序员,还是负责软件项目的经理,
通过每日学习这些课程,都会在个人生产力,准确率和工作满意度上有快速的增长.你所学到的技巧和开发习
惯和态度将为你在职业生涯中取得长期成功奠定基础.你将成为又一Pragmatic Programmer.



----------------------------------------------------------------
39.The Art of UNIX programming
  Author: Eric S. Raymond
  Publisher: Addison Wesley
  Published: October 2, 2003
  Amazon Reviews: Amazon.com
  Book Info: 荣获美国Software Development Productivity Award大奖作品!
  本书是作者封笔30年后历时5年创作而成,是一部难得的软件工程方面的佳作.作者首次将哲学,设计模式
,工具,文化和传统结合在一起,使得UNIX成为世界上最好且最具创新意义的软件,并展示了如何将其拓展到
Linux和当今的开源(open-source)运动中:通过取自最主要的开源项目中的示例,作者向UNIX和Linux编程人
员展示了如何更巧妙地创建软件,使其更雅致,更灵巧,更具可重用性且具有更长的生命期
  本书主要介绍了Unix系统领域中的设计和开发哲学,思想文化体系,原则与经验,由公认的Unix编程大师,
开源运动领袖人物之一Eric S.Raymond倾力多年写作而成.包括Unix设计者在内的多位领域专家也为本书贡
献了宝贵的内容.本书内容涉及社群文化,软件开发设计与实现,覆盖面广,内容深邃,完全展现了作者极其深
厚的经验积累和领域智慧.



----------------------------------------------------------------
40.Peopleware:Productive Projects and Teams
  Author: Tom DeMarco, Timothy Lister
  Publisher: Dorset House Publishing Co
  Published: February 28, 1999
  Amazon Reviews: Amazon.com
  Book Info: Tom Demarco 和Tim Lister 的"Peopleware:Productive Projects and Teams"第一版于
1987 年出版,专门讨论了软件开发和维护的团队管理问题,向传统的管理方法提出了挑战,推崇人本管理思想
,给予软件工人自由和信任.和<<人月神话>>一样,该书现在已经成为软件团队管理的经典之作.1995 年
,Larry Constantine 出版了一部题为"Constantine 论人件"的论文集,扩大了"人件"概念,把那些使用软件
的人也包括进来.1999 年2 月,<<人件>>第二版出版,增补了8 章新内容.这些增补的内容视角更加宽广,对比
较大型的组织中的团队如何运作进行了探索.



----------------------------------------------------------------
41.Computer graphics C Version 2nd ed
  Author: Donald Heam, M.Pauline Baker
  Publisher: Pearson US Imports & PHIPEs
  Published: May 24, 1996
  Amazon Reviews: Amazon.com
  Book Info: 这是计算机图形学领域的一部经典之作,作者Foley,van Dam等是国际图形学界的著名学者,
学术带头人,而且本书英文版自出版以来,一直是各国大学计算机图形学课程的主要教科书.本书是高等院校
计算机专业本科生,研究生计算机图形学课程的理想教材,是相关领域专业人员开展研究工作的优秀参考书.

----------------------------------------------------------------
42.Tricks of the 3D Game Programming Gurus-Advanced 3D Graphics and Rasterization
  Author: Andre LaMothe
  Amazon Reviews: Amazon.com
  Book Info: 本书是著名游戏程序设计类书籍作者Andre LaMothe的畅销书.在书中随处可见许多有趣但
又有一定难度的源程序.作者循循善诱地从程序设计的角度介绍了在Windows环境下进行游戏开发所需的全部
知识,包括Win32编程以及DirectX中所有主要组件(包括DirectDraw,DirectSound,DirectInput和
DirectMusic).书中还用单独的章节详细讲授了2D图形学和光栅化技术,游戏算法,多线程编程,文本游戏和解
析,人工智能(包括模糊逻辑,神经网络和遗传算法),物理建模(完全碰撞反应,动量传递和正反向运动学)及实
时模拟等游戏程序开发中的关键技术.



----------------------------------------------------------------
43.Compilers Principles, Techniques, and Tools
  Author: Alfred V. Aho, Ravi Seth, Jeffrey D. Ullman
  Publisher: Addison Wesley (January 1, 1986)
  Amazon Reviews: Amazon.com
  Book Info: 本书另外一个响亮的名字就是龙书.原因是这本书的封面上有条红色的龙.里面讲解的核心
编译原理至今都没有变过,所以一直到今天,它的价值都非凡.这本书最大的特点就是一开始就通过一个实际
的小例子,把编译原理的大致内容罗列出来,让很多编译原理的初学者很快心里有了个底,也知道为什么会有
这些理论,怎么运用这些理论.而这一点是我感觉国内的教材缺乏的东西,所以国内的教材都不是写给愿意自
学的读者,总之让人看了半天,却不知道里面的东西有什么用.



----------------------------------------------------------------
44.Computer Systems A Programmer's Perspective
  Author: Randal E. Bryant, David R. O'Hallaron
  Publisher: Prentice Hall; 1st edition (August 13, 2002)
  Amazon Reviews: Amazon.com
  Book Info: AMAZON五星图书,最伟大计算机科学教材之一
  卡耐基梅隆大学计算机学院院长,IEEE和ACM双院士倾力推出
  超过80所美国和世界一流大学计算机专业选用本书为教材
  本书英文版久负盛名,被众多专业人士称为"最伟大的计算机教材"之一,著名的美国卡内基梅隆大学计算
机科学系一直将本书作为教材使用,程序员眼中的透彻讲述计算机系统的扛鼎之作.作者Randal E. Bryant是
卡耐基梅隆大学的计算机科学系主任,ACM和IEEE双院士(Fellow),其研究成果多次获得ACM和IEEE颁发的大奖
.本书共分十三章,分别介绍了信息的表示和处理,程序的机器级表示,处理器体系结构,存储器层次结构,静态
和动态链接,虚拟存储器,系统级I/O,网络编程和并发编程等精彩内容.其目的是解释计算机系统的所有本质
概念,并向读者展示这些概念是如何实际地影响应用程序的正确性,性能和实用性.与其他主要针对系统构造
人员的系统类书籍不同,这本书是写给程序员的,是从程序员的角度来描述的.本书为软件和硬件之间搭起了
一个桥梁,它给出了一种帮助读者分别从硬件和软件的角度去理解一个程序及其行为的途径,这也填补了国内
计算机系统教学中的一个空白.本书的最大优点是帮助读者理解概念,让读者很清楚地在脑海中构造一个层次
型的计算机系统,从最低层数据在内存中的表示(如我们一直陌生的浮点数表示),到流水线指令的构成,到虚
拟存储器,到编译系统,到动态加载库,到最后的用户应用.本书提供了大量的例子和练习及部分答案.尤其值
得一提的是,对于每一个基本概念都有相应的笔头或程序试验,加深读者的理解.
  Book Reviews:
  我坚信从程序员的角度来看计算机系统对教会学生计算机的内部结构非常有帮助.
                             ----Kostas Daniilidis,宾夕法尼亚大学
  这本书讲述事物的方法与众不同,但是和我想要的课程进行方式类似.
                             ----John Greiner,Rice大学
  这是一项出色的工作,是这一领域教学方法的一次革命.
                             ----Michael Scott,罗切斯特大学

2008年10月12日星期日

Linux内核 main.c中的初始化

head.s在最后部分调用main.c中的start_kernel()函数,从而把控制权交给了它。所以启动程序从start_kernel()函数继续执行。这个函数是main.c乃至整个操作系统初始化的最重要的函数,一旦它执行完了,整个操作系统的初始化也就完成了。

如前所述,计算机在执行start_kernel()前处已经进入了386的保护模式,设立了中断向量表并部分初始化了其中的几项,建立了段和页机制,设立了九个段,把线性空间中用于存放系统数据和代码的地址映射到了物理空间的头4MB,可以说我们已经使386处理器完全进入了全面执行操作系统代码的状态。但直到目前为止,我们所做的一切可以说都是针对386处理器所做的工作,也就是说几乎所有的多任务操作系统只要使用386处理器,都需要作这一切。而一旦start_kernel()开始执行,Linux内核的真实面目就一步步的展现在你的眼前了。start_kernel()执行后,你就可以以一个用户的身份登录和使用Linux了。

让我们来看看start_kernel到底做了些什么,这里,通过介绍start_kernel()所调用的函数,我们来讨论start_kernel()的流程和功能。

我们仿照C语言函数的形式来进行这种描述,不过请注意,真正的start_kernel()函数调用子函数并不象我们在下面所写的这样简单,毕竟这本书的目的是帮助你深入分析Linux。我们只能给你提供从哪儿入手和该怎么看的建议,真正深入分析Linux,还需要你自己来研究代码。start_kernel()这个函数是在/init/main.c中,这里也只是将main.c中较为重要的函数列举出来。



start_kernel() /*定义于init/main.c */

{

……

setup_arch();

}

它主要用于对处理器、内存等最基本的硬件相关部分的初始化,如初始化处理器的类型(是在386,486,还是586的状态下工作,这是有必要的,比如说,Pentium芯片支持4MB大小的页,而386就不支持),初始化RAM盘所占用的空间(如果你安装了RAM盘的话)等。其中,setup_arch()给系统分配了intel系列芯片统一使用的几个I/O端口的口地址。



paging_init(); /*该函数定义于arch/i386/mm/init.c */



它的具体作用是把线性地址中尚未映射到物理地址上的部分通过页机制进行映射。这一部分在本书第六章有详细的描述,在这里需要特别强调的是,当paging_init()函数调用完后,页的初始化就整个完成了。



trap_init(); /*该函数在arch/i386/kernel/traps.c中定义*/



这个初始化程序是对中断向量表进行初始化,详见第四章。它通过调用set_trap_gate(或set_system_gate等)宏对中断向量表的各个表项填写相应的中断响应程序的偏移地址。

事实上,Linux操作系统仅仅在运行trap_init()函数前使用BIOS的中断响应程序(我们这里先不考虑V86模式)。一旦真正进入了Linux操作系统,BIOS的中断向量将不再使用。对于软中断,Linux提供一套调用十分方便的中断响应程序,对于硬件设备,Linux要求设备驱动程序提供完善的中断响应程序,而调用使用多个参数的BIOS中断就被这些中断响应程序完全代替了。

另外,在trap_init()函数里,还要初始化第一个任务的Ldt和TSS,把它们填入Gdt相应的表项中。第一个任务就是init_task这个进程,填写完后,还要把init_task的TSS和LDT描述符分别读入系统的TSS和LDT寄存器。



init_IRQ() /* 在arch/i386/kernel/irq.c中定义*/



这个函数也是与中断有关的初始化函数。不过这个函数与硬件设备的中断关系更密切一些。

我们知道intel的80386系列采用两片8259作为它的中断控制器。这两片级连的芯片一共可以提供16个引脚,其中15个与外部设备相连,一个用于级连。可是,从操作系统的角度来看,怎么知道这些引脚是否已经使用;如果一个引脚已被使用,Linux操作系统又怎么知道这个引脚上连的是什么设备呢?在内核中,同样是一个数组(静态链表)来纪录这些信息的。这个数组的结构在irq.h中定义:

struct irqaction {

void (*handler)(int, void *, struct pt_regs *);

unsigned long flags;

unsigned long mask;

const char *name;

void *dev_id;

struct irqaction *next;}



具体内容请参见第四章。我们来看一个例子:



static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)

{

outb(0,0xF0);

if (ignore_irq13 || !hard_math)

return;

math_error();

}

static struct irqaction irq13 = { math_error_irq, 0, 0, "math error", NULL, NULL };



该例子就是这个数组结构的一个应用,这个中断是用于协处理器的。在init_irq()这个函数中,除了协处理器所占用的引脚,只初始化另外一个引脚,即用于级连的2引脚。不过,这个函数并不仅仅做这些,它还为两片8259分配了I/O地址,对应于连接在管脚上的硬中断,它初始化了从0x20开始的中断向量表的15个表项(386中断门),不过,这时的中断响应程序由于中断控制器的引脚还未被占用,自然是空程序了。当我们确切地知道了一个引脚到底连接了什么设备,并知道了该设备的驱动程序后,使用setup_x86_irq这个函数填写该引脚对应的386的中断门时,中断响应程序的偏移地址才被填写进中断向量表。



sched_init() /*在/kernel/sched.c中定义*/

看到这个函数的名字可能令你精神一振,终于到了进程调度部分了,但在这里,你非但看不到进程调度程序的影子,甚至连进程都看不到一个,这个程序是名副其实的初始化程序:仅仅为进程调度程序的执行做准备。它所做的具体工作是调用init_bh函数(在kernel/softirq.c中)把timer,tqueue,immediate三个任务队列加入下半部分的数组。



time_init()/*在arch/i386/kernel/time.c中定义*/

时间在操作系统中是个非常重要的概念。特别是在Linux,Unix这种多任务的操作系统中它更是作为主线索贯穿始终,之所以这样说,是因为无论进程调度(特别是时间片轮转算法)还是各种守护进程(也可以称为系统线程,如页表刷新的守护进程)都是根据时间运作的。可以说,时间是他们运行的基准。那么,在进程和线程没有真正启动之前,设定系统的时间就是一件理所当然的事情了。

我们知道计算机中使用的时间一般情况下是与现实世界的时间一致的。当然,为了避开CIH,把时间跳过每月26号也是种明智的选择。不过如果你在银行或证交所工作,你恐怕就一定要让你计算机上的时钟与挂在墙上的钟表分秒不差了。还记得CMOS吗?计算机的时间标准也是存在那里面的。所以,我们首先通过get_cmos_time()函数设定Linux的时间,不幸的是,CMOS提供的时间的最小单位是秒,这完全不能满足需要,否则CPU的频率1赫兹就够了。Linux要求系统中的时间精确到纳秒级,所以,我们把当前时间的纳秒设置为0。

完成了当前时间的基准的设置,还要完成对8259的一号引脚上的8253(计时器)的中断响应程序的设置,即把它的偏移地址注册到中断向量表中去。



parse_options() /*在main.c中定义*/

这个函数把启动时得到的参数如debug,init等等从命令行的字符串中分离出来,并把这些参数赋给相应的变量。这其实是一个简单的词法分析程序。



console_init() /*在linux/drivers/char/tty_io.c中定义*/

这个函数用于对终端的初始化。在这里定义的终端并不是一个完整意义上的TTY设备,它只是一个用于打印各种系统信息和有可能发生的错误的出错信息的终端。真正的TTY设备以后还会进一步定义。



kmalloc_init() /*在linux/mm/kmalloc.c中定义*/

kmalloc代表的是kernel_malloc的意思,它是用于内核的内存分配函数。而这个针对kmalloc的初始化函数用来对内存中可用内存的大小进行检查,以确定kmalloc所能分配的内存的大小。所以,这种检查只是检测当前在系统段内可分配的内存块的大小,具体内容参见第六章内存分配与回收一节。



下面的几个函数是用来对Linux的文件系统进行初始化的,为了便于理解,这里需要把Linux的文件系统的机制稍做介绍。不过,这里是很笼统的描述,目的只在于使我们对初始化的解释工作能进行下去,详细内容参见第八章的虚拟文件系统。

虚拟文件系统是一个用于消灭不同种类的实际文件系统间(相对于VFS而言,如ext2,fat等实际文件系统存在于某个磁盘设备上)差别的接口层。在这里,您不妨把它理解为一个存放在内存中的文件系统。它具体的作用非常明显:Linux对文件系统的所有操作都是靠VFS实现的。它把系统支持的各种以不同形式存放于磁盘上或内存中(如proc文件系统)的数据以统一的形式调入内存,从而完成对其的读写操作。(Linux可以同时支持许多不同的实际文件系统,就是说,你可以让你的一个磁盘分区使用windows的FAT文件系统,一个分区使用Unix的SYS5文件系统,然后可以在这两个分区间拷贝文件)。为了完成以及加速这些操作,VFS采用了块缓存,目录缓存(name_cach),索引节点(inode)缓存等各种机制,以下的这些函数,就是对这些机制的初始化。



inode_init() /*在Linux/fs/inode.c中定义*/

这个函数是对VFS的索引节点管理机制进行初始化。这个函数非常简单:把用于索引节点查找的哈希表置入内存,再把指向第一个索引节点的全局变量置为空。



name_cache_init() /*在linux/fs/dcache.c中定义*/

这个函数用来对VFS的目录缓存机制进行初始化。先初始化LRU1链表,再初始化LRU2链表。



Buffer_init()/*在linux/fs/buffer.c中定义*/



这个函数用来对用于指示块缓存的buffer free list初始化。



mem_init() /* 在arch/i386/mm/init.c中定义*/



启动到了目前这种状态,只剩下运行/etc下的启动配置文件。这些文件一旦运行,启动的全过程就结束了,系统也终将进入我们所期待的用户态。现在,让我们回顾一下,到目前为止,我们到底做了哪些工作。

其实,启动的每一个过程都有相应的程序在屏幕上打印与这些过程相应的信息。我们回顾一下这些信息,整个启动的过程就一目了然了。

当然,你的计算机也许速度很快,你甚至来不及看清这些信息,系统就已经就绪,“Login:”就已经出现了,不要紧,登录以后,你只要打一条dmesg | more命令,所有这些信息就会再现在屏幕上。



【Loading ……】出自bootsect.S ,表明内核正被读入。

【uncompress ……】很多情况下,内核是以压缩过的形式存放在磁盘上的,这里是解压缩的过程。



下面这部分信息是在main.c的start_kernel函数被调用时显示的。

【 Linux version 2.2.6 (root@lance) (gcc version 2.7.2.3)】Linux的版本信息和编译该内核时所用的gcc的版本。

【 Detected 199908264 Hz processor】调用init_time()时打出的信息。

【Console:colour VGA+ 80x25,1 virtaul console(max 63)】调用 console_init()打出的信息 。初始化的终端屏幕使用彩色VGA模式,最大可以支持63个终端。

【 Memory: 63396k/65536k available (848k kernel code, 408k reserved, 856k data)】调用 init_mem()时打印的信息。内存共计65536K,其中空闲内存为63396K,已经使用的内存中,有848K用于存放内核代码,404K保留,856K用于内核数据。

【 VFS:Diskquotas version dquot_6.4.0 initialized】调用dquote_init()打出的信息 。quota是用来分配用户磁盘定额的程序。关于这个程序请参看第八章。



以下是对设备的初始化 :

【 PCI: PCI BIOS revision 2.10 entry at 0xfd8d1 |

PCI: Using configuration type 1 |

PCI: Probing PCI hardware 】调用pci_init()函数时显示的信息。

【 Linux NET4.0 for Linux 2.2

Based upon Swansea University Computer Society NET3.039

NET4: Unix domain sockets 1.0 for Linux NET4.0.

NET4: Linux TCP/IP 1.0 for NET4.0

IP Protocols: ICMP, UDP, TCP】调用socket_init()函数时打印的信息。使用Linux的4.0版本的网络包,采用sockets 1.0 和1.0版本的TCP/IP协议,TCP/IP协议中包含有ICMP,UDP,TCP三组协议。



【 Detected PS/2 Mouse Port。

Sound initialization started

Sound initialization complete

Floppy drive(s): fd0 is 1.44M

Floppy drive(s): fd0 is 1.44M

FDC 0 is a National Semiconductor PC87306 】调用device_setup()函数时打印的信息。包括对ps/2型鼠标,声卡和软驱的初始化。



看完上面这一部分代码和与之相应的信息,你应该发现,这些初始化程序并没有完成操作系统的各个部分的初始化,比如说,文件系统的初始化只是初始化了几个内存中的数据结构,而更关键的文件系统的安装还没有涉及,其实,这是在init进程建立后完成的。下面,就是start_kernel()的最后一部分内容。

Plan ९ 的八卦

在 Windows 下喜欢用 FTP 的同学抱怨 Linux 下面没有如 LeapFTP 那样的方便的工具. 在苹果下面用惯了 Cyberduck 的同学可能也会抱怨 Linux 下面使用 FTP 和 SFTP 是一件麻烦的事情. 其实一点都不麻烦, 因为在 LINUX 系统上压根就不需要用 FTP. 为什么呢? 因为一行简单的配置之后, 你就可以像使用本机文件一样使用远程的任何文件. 无论是想编辑, 查看还是删除重命名, 都和本机文件一样的用. 这么神奇的功能到底如何使用呢, 待我一一道来.

首先, 如果你的内核版本是 2.6.14 或者更新(uname -r 可以查看你的内核版本), 你的机器上的已经有了这个支持了. 在这种情况下, 你可以使用:

sudo modprobe fuse

激活内核模块. 然后, 比如说, 你想SSH远程 remote.com 上的 /dir 目录, 作为本机的 ldir 目录, 你可以使用:

sshfs name@remote.com:/dir /ldir

然后, 您就可以完全在 ldir 目录下操作任何的远程机器上的文件了. 是不是很简单 :)

如果要使用 ftp, 我们要使用一个叫做 curlftpfs 的开源软件. 幸运的是, 你可以直接使用 apt-get install curlftpfs 直接得到他.

安装结束后, 我们依然使用

curlftpfs ftp://user:pass@ftp.remote.com/dir ldir/

就可以把远程的目录当成本地的目录一样使用的. 拷贝啊重命名啊都可以. (当远程的内容直接能被你访问的时候, 谁拷贝啊 :)

说到这里, 聪明的读者肯定要说: 靠, 远程的文件都能当成本机的用, 那太好了, 整个互联网就是我的磁盘嘛. 你还真说对了, 对于一个用户来说, 协议是不重要的, 重要的是数据. Gmail 不是有N个Gb的大小么, 让我们直接把 gmail 当磁盘好了. 于是有了 Gmail FS. 这样, 你可以给你的邮件标题做支持正则表达式的查找噢 :)

除此, 还有 wikipediaFS, 可以用自己喜欢的编辑器直接编辑维基百科的文章. 还有 flickrFS. 直接用自己喜欢的编辑器可以编辑图像元信息, 还能 chmod 754 让图像只能被朋友访问噢 :)

以上的这些酷实现, 都是 FUSE 这个内核模块作为基础支持的. 那么, 这个牛逼的网络也是文件的点子是哪个牛逼的人想出来的呢? 答案是 UNIX 的发源地, 贝尔实验室. 确切的说, 是在设计 UNIX 的继承者– Plan 9 的过程中提出来的. (小八卦: UTF-8, 就是世界上现在最通用的字符编码体系, 就是 Plan 9 操作系统的一个副产品).

一切都是文件这个点子倒不是什么新的点子, 在 The Unix Programming Environment 这本圣经里面就旗帜鲜明的打出 “UNIX下一切都是文件”的旗号. 但是毕竟旗号是旗号, 现实是现实. 关于文件的抽象在其后的发展中发现了这样那样的局限, 于是恶名远扬的 ioctl 函数被引进系统. 所以口号是口号, 实现是实现. 显然当初设计 UNIX 的几个哥们很不满意, 所以搞了一个 Plan 9 (搞 Plan 9 的人就是写 The Unix Programming Environment 的人). 在 Plan 9 系统中, 一切都是文件, 显卡是文件, 内存是文件, 进程是文件, 网络是文件…

等等, 熟悉 Linux 的用户要说了, 在 Linux 下面, 进程的确是文件啊. ls /proc 就能看到当前所有的进程, 不也是文件么. 是呀, Linux 这个就是和 Plan 9 学来的. 但是 Linux 学得不彻底, 因为这个文件系统的访问接口并不完整: 你不能通过 rm 一个文件杀死一个进程. 也不能通过 cp 拷贝出一个进程. 而在 Plan 9 上, 你不光能通过普通的文件操作命令去控制进程, 你还能 mv 一个进程. 我们刚才说了, 进程就是文件, 还能把其他机器上的文件当成本机一样用. 屏幕前聪明的你肯定一下子悟到了: 一定这居然是一个分布式的操作系统啊! 在这个系统里, 进程可以被其他计算机看到, 并且控制. 而管道可以横跨不同机器的不同进程, 这简直是把单机的概念都给抹杀了, 简直就是”网络就是计算机啊”.

熟悉互联网的读者都知道最近炒得很热的云计算啥的, 对用户无非就是互联网作为硬盘, 对公司无非就是分布式的操作系统协同工作, 在屏幕前的您肯定如我一样, 一拍大腿说: 靠, 贝尔实验室养得不是计算机科学家, 而是一大批未来学家啊. 30多年前人家搞互联网, 而今我们用互联网. 20年前人家用GUI, 如今我们用GUI. 10年前人家搞云计算, 而今我们炒概念闲扯淡. 差距啊.

2008年9月29日星期一

计算机编年史

一、机械计算机时代的拓荒者

在西欧,由中世纪进入文艺复兴时期的社会大变革,大大促进了自然科学技术的发展,人们长期被神权压抑的创造力得到空前释放。其中制造一台能帮助人进行计算的机器,就是最耀眼的思想火花之一。从那时起,一个又一个科学家为把这一思想火花变成引导人类进入自由王国的火炬而不懈努力。但限于当时的科技总体水平,大都失败了,这就是拓荒者的共同命运:往往见不到丰硕的果实。后人在享用这甜美的时候,应该能从中品出一些汗水与泪水的滋味……

1614: 苏格兰人John Napier (1550-1617)发表了一篇论文,其中提到他发明了一种可以计算四则运算和方根运算的精巧装置。
1623: Wilhelm Schickard (1592-1635)制作了一个能进行六位以内数加减法,并能通过铃声输出答案的"计算钟"。通过转动齿轮来进行操作。
1625: William Oughtred (1575-1660) 发明计算尺
1642: 法国数学家Pascal 在WILLIAM Oughtred计算尺的基础上将计算尺加以改进,能进行八位计算。并且还卖出了许多,成为一种时髦的商品。
在此插入〈PASCAL像〉

1668: 英国人Samuel Morl和 (1625-1695)制作了一个非十进制的加法装置,适宜计算钱币。
1671: 德国数学家Gottfried Leibniz设计了一架可以进行乘法,最终答案可以最大达到16位。
1775: 英国Charles制作成功了一台与 Leibniz's 的计算机类似的机器。但更先进一些。
1776: 德国人Mathieus Hahn成功的制作了一台乘法器。
1801: Joseph-Maire Jacuard 开发了一台能用穿孔卡片控制的自动织布机。
1820: 法国人Charles Xavier Thomas de Colmar (1785-1870),制作成功第一台成品计算机,非常的可靠,可以放在桌面上,在后来的90多年间一直在市场上出售。
1822: 英国人Charles Babbage (1792-1871)设计了差分机和分析机,其中设计的理论非常的超前,类似于百年后的电子计算机,特别是利用卡片输入程序和数据的设计被后人所采用。
1832: Babbage 和Joseph Clement 制成了一个差分机的成品,开始可以进行6位数的运算。后来发展到20位、30位,尺寸将近一个房子那么大。结果以穿孔的形式输出。但限于当时的制造技术,他们的设计难以制成。
1834: 斯德哥尔摩的George Scheutz用木头做了一台差分机。
1834: Babbage 设想制造一台通用的分析机,在只读存储器(穿孔卡片)中存储程序和数据,Babbage在以后的时间继续他的研究工作,并于1840年将操作数提高到了40位,并基本实现了控制中心(CPU)和存储程序的设想,而且程序可以根据条件进行跳转,能在几秒内作出一般的加法,几分钟内作出乘除法。


1842: Babbage的差分机项目因为研制费用昂贵,被政府取消。但他自己仍花费大量的时间和精力于他的分析机研究。
1843: Scheutz 和他的儿子Edvard Scheutz 制造了一台差分机,瑞典政府同意继续支持他们的研究工作。
1847: Babbage 花两年时间设计了一台较简易的、31位的差分机,但没有人感兴趣并支持他造出这台机器。但后来伦敦科学博物馆用现代技术复制出这台机器后发现,它确实能准确的工作。
1848: 英国数学家George Boole创立二进制代数学。提前差不多一个世纪为现代二进制计算机铺平了道路。
1853: 令Babbage感到高兴的是,Scheutzes制造成功了真正意义上的比例差分机,能进行15位数的运算。象Babbage所设想的那样输出结果。后来伦敦的Brian Donkin又造出了更可靠的第二台。
1858: 第一台制表机被Albany的Dudley天文台买走。第二台被英国政府买走。但天文台并没有将其充分利用,后来被送进了博物馆。而第二台却被幸运的使用了很长时间。
1871: Babbage 制造了分析机的部分部件和印表机。
1878: 纽约的西班牙人Ramon Verea,制造成功桌面计算器。比前面提到的都要快。但他对将其推向市场不感兴趣,只是想表明,西班牙人可以比美国人做的更好。
1879: 一个调查委员会开始研究分析机是否可行,最后他们的结论是:分析机根本不可能工作。此时Babbage 已经去世了。调查之后,人们将他的分析机彻底遗忘了。但Howard Aiken 例外。
1885: 这时期更多的计算机涌现出来。如美国、俄国、瑞典等。他们开始用有槽的圆柱代替易出故障的齿轮。
1886: 芝加哥的Dorr E. Felt (1862-1930), 制造成了他的计算机。这是第一台用按键操作的计算器,而且速度非常快,按键抬起,结果也就出来了。
1889: Felt推出桌面印表计算器。
1890: 1890美国人口普查。1880年的普查人工用了7年的时间进行统计。这意味着1890年的统计将会超过10年。美国人口普查部门希望能得到一台机器帮助提高普查的效率。Herman Hollerith,建立制表机公司的那个人,后来他的公司发展成了IBM公司。借鉴了Babbage的发明,用穿孔卡片存储数据,并设计了机器。结果仅仅用了6个周就得出了准确的数据(62622250人)。Herman Hollerith大发其财。
1892: 圣多美和普林西比的William S. Burroughs (1857-1898),制作成功了一台比Felt的功能更强的机器,真正开创了办公自动化工业。
1896: Herman Hollerith创办了IBM公司的前身。
--------------------------------------------------------------------------------

1900

1906: Henry Babbage, Charles Babbage 的儿子,在R. W. Munro的支持下,完成了父亲设计的分析机,但也仅能证明它能工作,而没有将其作为产品推出。

二、电子计算机最初的日子里

在这之前的计算机,都是基于机械运行方式,尽管有个别产品开始引入一些电学内容,却都是从属与机械的,还没有进入计算机的灵活:逻辑运算领域。而在这之后,随着电子技术的飞速发展,计算机就开始了由机械向电子时代的过渡,电子越来越成为计算机的主体,机械越来越成为从属,二者的地位发生了变化,计算机也开始了质的转变。下面就是这一过渡时期的主要事件:

1906: 美国的Lee De Forest发明了电子管。在这之前造出数字电子计算机是不可能的。这为电子计算机的发展奠定了基础。
回页首

--------------------------------------------------------------------------------

1910

1920
1924年2月:IBM,一个具有划时代意义的公司成立。
--------------------------------------------------------------------------------

1930
1935: IBM推出IBM 601机。 这是一台能在一秒钟算出乘法的穿孔卡片计算机。这台机器无论在自然科学还是在商业意义上都具有重要的地位。大约造了1500台。
1937: 英国剑桥大学的Alan M. Turing (1912-1954)出版了他的论文 ,并提出了被后人称之为"图灵机"的数学模型。
1937: BELL试验室的George Stibitz展示了用继电器表示二进制的装置。尽管仅仅是个展示品,但却是第一台二进制电子计算机。
1938: Claude E. Shannon 发表了用继电器进行逻辑表示的论文。
1938: 柏林的Konrad Zuse 和他的助手们完成了一个机械可编程二进制形式的计算机,其理论基础是Boolean代数。后来命名为Z1。它的功能比较强大,用类似电影胶片的东西作为存储介质。可以运算七位指数和16位小数。可以用一个键盘输入数字,用灯泡显示结果。
1939 1月1日: 加利福尼亚的David Hewlet和William Packard 在他们的车库里造出了Hewlett-Packard计算机。名字是两人用投硬币的方式决定的。包括两人名字的一部分。
1939年11月: 美国John V. Atanasoff和他的学生Clifford Berry 完成了一台16位的加法器,这是第一台真空管计算机。
1939: 二次世界大战的开始,军事需要大大促进了计算机技术的发展。
1939: Zuse和Schreyer 开始在他们的Z1计算机的基础上发展Z2计算机。并用继电器改进它的存储和计算单元。但这个项目因为Zuse服兵役被中断了一年。
1939/1940: Schreyer利用真空管完成了一个10位的加法器,并使用了氖灯做存储装置。
回页首

--------------------------------------------------------------------------------

1940
1940年1月: Bell实验室的Samuel Williams和Stibitz制造成功了一个能进行复杂运算的计算机。大量使用了继电器,并借鉴了一些电话技术, 采用了先进的编码技术。
1941夏季: Atanasoff和学生Berry完成了能解线性代数方程的计算机,取名叫"ABC"(Atanasoff-Berry Computer),用电容作存储器,用穿孔卡片作辅助存储器,那些孔实际上是"烧"上的。 时钟频率是60HZ,完成一次加法运算用时一秒。
1941年12月: 德国Zuse制作完成了Z3计算机的研制。这是第一台可编程的电子计算机。可处理7位指数、14位小数。使用了大量的真空管。每秒种能作3到4次加法运算。一次乘法需要3到5秒。
1943: 1943年到1959年时期的计算机通常被称作第一代计算机。使用真空管,所有的程序都是用机器码编写,使用穿孔卡片。典型的机器就是: UNIVAC。
1943年1月: Mark I,自动顺序控制计算机在美国研制成功。整个机器有51英尺长,重5吨,75万个零部件,使用了3304个继电器,60个开关作为机械只读存储器。程序存储在纸带上,数据可以来自纸带或卡片阅读器。被用来为美国海军计算弹道火力表。
1943年4月: Max Newman、Wynn-Williams和他们的研究小组研制成功"Heath Robinson",这是一台密码破译机,严格说不是一台计算机。但是其使用了一些逻辑部件和真空管,其光学装置每秒钟能读入2000个字符。同样具有划时代的意义。
1943年9月 : Williams和Stibitz完成了"Relay Interpolator",后来命名为"Model II Relay Calculator"。这是一台可编程计算机。同样使用纸带输入程序和数据。其运行更可靠,每个数用7个继电器表示,可进行浮点运算。
1943年12月: 最早的可编程计算机在英国推出,包括2400个真空管,目的是为了破译德国的密码,每秒能翻译大约5000个字符 ,但使用完后不久就遭到了毁坏。据说是因为在翻译俄语的时候出现了错误。
1946: ENIAC (Electronic Numerical Integrator 和 Computer): 第一台真正意义上的数字电子计算机。开始研制于1943年,完成于1946年。负责人是John W. Mauchly和J. Presper Eckert。重30吨,18000个电子管,功率25千瓦。主要用于计算弹道和氢弹的研制。

三、晶体管计算机的发展
真空管时代的计算机尽管已经步入了现代计算机的范畴,但其体积之大、能耗之高、故障之多、价格之贵大大制约了它的普及应用。直到晶体管被发明出来,电子计算机才找到了腾飞的起点,一发而不可收……

1947: Bell实验室的William B. Shockley、 John Bardeen和Walter H. Brattain.发明了晶体管,开辟了电子时代新纪元。
1949: EDSAC:剑桥大学的Wilkes和他的小组建成了一台存储程序的计算机。输入输出设备仍是纸带。
1949: EDVAC (electronic discrete variable computer):第一台使用磁带的计算机。这是一个突破,可以多次在其上存储程序。这台机器是John von Neumann提议建造的。
1949: "未来的计算机不会超过1.5吨。"这是当时科学杂志的大胆预测。
回页首

--------------------------------------------------------------------------------

1950
1950: 软磁盘由东京帝国大学的Yoshiro Nakamats发明。其销售权由IBM公司获得。开创存储时代新纪元。
1950: 英国数学家和计算机先驱Alan Turing说:计算机将会具有人的智慧,如果一个人和一台机器对话,对于提出和回答的问题,这个人不能区别到底对话的是机器还是人,那么这台机器就具有了人的智能。
在此插入〈阿兰图灵像〉

1951: Grace Murray Hopper完成了高级语言编译器。
1951: Whirlwind:美国空军的第一个计算机控制实时防御系统研制完成。
1951: UNIVAC-1:第一台商用计算机系统。设计者:J. Presper Eckert 和John Mauchly。被美国人口普查部门用于人口普查,标志着计算机的应用进入了一个新的、商业应用的时代。
1952: EDVAC (Electronic Discrete Variable Computer):由Von Neumann领导设计并完成。 取名:电子离散变量计算机。
1953: 此时世界上大约有100台计算机在运转。
1953: 磁芯存储器被开发出来。

在此插入〈磁芯存储器图〉
1954: IBM的John Backus和他的研究小组开始开发 FORTRAN (FORmula TRANslation),1957年完成。是一种适合科学研究使用的计算机高级语言。
1956: 第一次有关人工智能的会议在Dartmouth 学院召开。
1957: IBM开发成功第一台点阵打印机。
1957: FORTRAN 高级语言开发成功。

四、集成电路,现代计算机插上腾飞的翅膀

尽管晶体管的采用大大缩小了计算机的体积、降低了其价格,减少了故障。但离人们的要求仍差很远,而且各行业对计算机也产生了较大的需求,生产更能更强、更轻便、更便宜的机器成了当务之急,而集成电路的发明正如“及时雨”,当春乃发生。其高度的集成性,不仅仅使体积得以减小,更使速度加快,故障减少。人们开始制造革命性的微处理器。计算机技术经过多年的积累,终于驶上了用硅铺就的高速公路。

1958年9月12日: 在Robert Noyce(INTEL公司的创始人)的领导下,发明了集成电路。不久又推出了微处理器。但因为在发明微处理器时借鉴了日本公司的技术,所以日本对其专利不承认,因为日本没有得到应有的利益。过了30年,日本才承认,这样日本公司可以从中得到一部分利润了。但到2001年,这个专利也就失效了。
1959: 1959年到1964年间设计的计算机一般被称为第二代计算机。大量采用了晶体管和印刷电路。计算机体积不断缩小,功能不断增强,可以运行FORTRAN和COBOL ,接收英文字符命令。出现大量应用软件。
1959: Grace Murray Hopper开始开发COBOL (COmmon Business-Orientated Language)语言,完成于1961年。
回页首

--------------------------------------------------------------------------------

1960
1960: ALGOL:第一个结构化程序设计语言推出。
1961: IBM的Kennth Iverson推出APL编程语言。
1963: PDP-8:DEC公司推出第一台小型计算机。
1964: 1964年到1972年的计算机一般被称为第三代计算机。大量使用集成电路,典型的机型是IBM360系列。
1964: IBM发布PL/1编程语言。
1964: 发布IBM 360首套系列兼容机。
1964: DEC发布PDB-8 小型计算机。
1965: 摩尔定律发表,处理器的性能每年提高一倍。后来其内容又发生了改变。

在此插入〈摩尔像〉
1965: Lofti Zadeh创立模糊逻辑,用来处理近似值问题。
1965: Thomas E. Kurtz和John Kemeny完成BASIC(Beginners All Purpose Symbolic Instruction Code)语言的开发。特别适合计算机教育和初学者使用,得到了广泛的推广。
1965: Douglas Englebart 提出鼠标器的设想,但没有进一步的研究。直到1983年被苹果电脑公司大量采用。
1965: 第一台超级计算机CD6600开发成功。
1967: Niklaus Wirth开始开发PASCAL语言,1971年完成。
1968: Robert Noyce和他的几个朋友创办了INTEL公司。
1968: Seymour Paper和他的研究小组在MIT开发了LOGO语言。
1969: ARPANET计划开始启动,这是现代INTERNET的雏形。
1969 年4月7日: 第一个网络协议标准RFC推出。
1969: EIA (Electronic Industries Associa
回页首

--------------------------------------------------------------------------------

1970
1970: 第一块RAM芯片由INTEL推出,容量1K。
1970: Ken Thomson和Dennis Ritchie开始开发UNIX操作系统。
1970: Forth编程语言开发完成。
1970: Internet的雏形ARPAnet (Advanced Research Projects Agency network) 基本完成。开始向非军用部门开放,许多大学和商业部门开始接入。
1971年11月15日: Marcian E. Hoff在INTEL公司开发成功第一块微处理器4004,含2300个晶体管,是个4位系统,时钟频率108KHz ,每秒执行6万条指令。

在此插入〈4004图像〉

在后来的日子里,处理器发展主要指标一览。
处理器 主频 每秒百万条指令
4004 108 KHz 0.06
8080 2MHz 0.5
68000 8MHz 0.7
8086 8MHz 0.8
68000 16 MHz 1.3
68020 16 MHz 2.6
80286 12MHz 2.7
68030 16MHz 3.9
386 SX 20 MHz 6
68030 25 MHz 6.3
68030 40MHz 10
386 DX 33MHz 10
486 DX 25MHz 20
486 DX2-50 50MHz 35
486 DX4/100 100MHz 60
Pentium 66MHz 100
Pentium 133MHz 240
Pentium 233MHz MMX 435
Pentium Pro 200 MHz 440
Pentium II 233MHz 560
Pentium II 333MHz 770
1971: PASCAL语言开发完成。
1972: 1972年以后的计算机习惯上被称为第四代计算机。基于大规模集成电路,及后来的超大规模集成电路。计算机功能更强,体积更小。人们开始怀疑计算机能否继续缩小,特别是发热量问题能否解决?人们开始探讨第五代计算机的开发。
1972: C语言的开发完成。其主要设计者是UNIX系统的开发者之一 Dennis Ritche。这是一个非常强大的语言,开发系统软件,特别受人喜爱。
1972: Hewlett-Packard发明了第一个手持计算器。
1972年4月1日: INTEL推出8008微处理器。
1972: ARPANET开始走向世界,INTERNET革命拉开序幕。
1973: 街机游戏Pong发布,得到广泛的欢迎。发明者Nolan Bushnell ,后来Atari 的创立者。
1974: 第一个具有并行计算机体系结构的CLIP-4推出。
五、计算机技术渐入辉煌
在这之前,计算机技术主要集中在大型机和小型机领域发展,但随着超大规模集成电路和微处理器技术的进步,计算机进入寻常百姓家的技术障碍已层层突破。特别是从INTEL发布其面向个人机的微处理器8080之后,这一浪潮便汹涌澎湃起来,同时也涌现了一大批信息时代的弄潮儿,如乔布斯、比尔.盖茨等,至今他们对计算机产业的发展还起着举足轻重的作用。在此时段,互联网技术、多媒体技术也得到了空前的发展,计算机真正开始改变人们的生活。

1974年4月1日: INTEL发布其8位的微处理器芯片8080。
1974年12月: MITS发布Altair 8800,第一台商用个人计算机,价值397美元,内存有256个字节。
1975: Bill Gates和Paul Allen完成了第一个在MITS 的Altair计算机上运行的BASIC程序。
1975: IBM公司介绍了他的激光打印机技术。1988年向市场推出其彩色激光打印机。
1975: Bill Gates和Paul Allen创办MicorSoft公司。现在成为最大、最成功的软件公司。三年后就收入50万美元,增加到15个人。1992年达28亿美元,1万名雇员。其最大的突破性发展是在1981年为IBM 的PC机开发操作系统,从此后便开始了对计算机业的巨大影响。
1975: IBM 5100发布。
1976: Stephen Wozinak和Stephen Jobs创办苹果计算机公司。并推出其Apple I 计算机。
1976: Zilog推出Z80处理器。8位微处理器。 CP/M就是面向其开发的操作系统。许多着名的软件如:Wordstar 和dBase II基于此款处理器。
1976: 6502, 8 位微处理器发布,专为Apple II计算机使用。
1976: Cray 1,第一台商用超级计算机。集成了20万个晶体管,每秒进行1.5亿次浮点运算。
1977年5月: Apple II 型计算机发布。
1978: Commodore Pet发布:有 8K RAM,盒式磁带机,9英寸显示器。
1978年6月8日: INTEL发布其16位微处理器8086。但因其非常昂贵,又推出8位的8088满足市场对低价处理器的需要,并被IBM的第一代PC机所采用。其可用的时钟频率为4.77、8、10MHz。大约有300条指令,集成了29000更晶体管。
1979: 街机游戏"太空入侵者"发布,引起轰动。很快便使得类似的游戏机大规模流行起来,其收入超过了美国电影业。
1979: Jean Ichbiah 开发完成Ada计算机语言。
1979年6月1日: INTEL发布了8位的8088微处理器,纯粹为了迎合低价电脑的需要。
1979: Commodore PET 发布了采用1MHz的6502处理器,单色显示器、8K内存的计算机,并且可以根据需要购买更多的内存扩充。
1979: 发明了低密盘。
1979: Motorola公司发布68000微处理器。主要供应Apple公司的Macintosh ,后继产品68020用在Macintosh II机型上。
1979: IBM公司眼看着个人计算机市场被苹果等电脑公司占有,决定也开发自己的个人计算机,为了尽快的推出自己的产品,他们大量的工作是与第三方合作,其中微软公司就承担了其操作系统的开发工作。很快他们便在1981年8月12日推出了IBM-PC。但同时也为微软后来的崛起,施足了肥料。
1980~1990
1980:“只要有1兆内存就足够DOS尽情表演了”。微软公司开发DOS初期时说。今天来听这句话有何感想呢?
1980年10月: MS-DOS/PC-DOS开发工作开始了。但微软并没有自己独立的操作系统,他们买来别人的操作系统并加以改进。但IBM测试时竟发现有300个BUG。于是他们又继续改进,最初的DOS1.0有4000行汇编程序。
1981: Xerox开始致力于图形用户界面、图标、菜单和定位设备(如鼠标)的研制。结果研究成果为苹果所借鉴。而苹果电脑公司后来又指控微软剽窃了他们的设计,开发了WINDOWS系列软件。
1981: INTEL发布的80186/80188芯片,很少被人使用,因为其寄存器等与其他不兼容。但其采用了直接存储器访问技术和时间片分时技术。
1981年8月12日: IBM发布其个人计算机,售价2880美元。该机有64K内存、单色显示器、可选的盒式磁带驱动器、两个160KB单面软盘驱动器。这台机器取得了比预想的还要大的成功。
1981年8月12日: MDA (Mono Display Adapter, text only) 能够显示文本的单色显示器随IBM-PC机发布。
1981年8月12日: MS-DOS 1.0,PC-DOS1.0发布。Microsoft是受IBM委托开发DOS操作系统,他们从Tim Paterson那里购买了一个叫86-DOS 的程序并加以改进。从IBM卖出去的叫PC-DOS。从Microsoft卖出去的叫MS-DOS。Micorsoft与IBM的合作一直到1991年的DOS5.0为止。最初的DOS1.0非常的简陋,每张盘上只一个根目录,不支持子目录。直到1983年3月的2.0版才有所改观。MS-DOS在1995年以前一直是与IBM-PC兼容的操作系统,WINDOWS95推出并迅速占领市场之后,其最后一个版本命名为DOS7.0。现在微软的操作系统已经在世界大多数计算机上运行了。
1982: 基于TCP/IP协议的INTERNET初具规模。
1982: 基于6502微处理器的计算机大受欢迎,特别是在学校大量普及。
1982 年1月: Commodore 64计算机发布,价格:595美元。
1982 年2月: 80286发布。时钟频率提高到20MHz,并增加了保护模式,可访问16M内存。支持1GB以上的虚拟内存。每秒执行270万条指令,集成了134000个晶体管。
1982: Compaq公司发布了其IBM-PC兼容机。
1982: MIDI(Musical Instrument Digital Interface)标准制定。允许计算机连接标准的类似键盘数字乐器。
1982: Sony和Phillips公布了压缩音频的红皮书。很快得到欧美的认同。
1982年3月: MS-DOS 1.25PC-DOS 1.1
1982 年4月: Sinclair ZX Spectrum发布:基于Z80芯片,时钟频率3.5MHz。能显示8种颜色。
1982年5月: IBM推出双面320K的软盘驱动器。
1983 年1月: IBM PC在欧洲展示。
1983: Borland公司成立。
1983春季: IBM XT机发布,增加了10兆的硬盘,128K RAM,一个软驱、单色显示器、一台打印机、可以增加一个8087数字协处理器。价格5000美元。
1983年3月: MS-DOS 2.0、PC-DOS 2.0增加了类似UNIX分层目录的管理形式。
1983年10月: MS-DOS 2.25,包括支持其他字符设置,开辟东方市场。
1984: DNS (Domain Name Server) 域名服务器发布,互连网上有1000多台主机运行。
1984: Hewlett-Packard发布了优异的激光打印机,HP也在喷墨打印机上保持领先技术。
1984年1月: Apple 的Macintosh发布。基于Motorola 68000微处理器。可以寻址16M。
1984 年8月: MS-DOS 3.0、PC-DOS 3.0、IBM AT发布,采用ISA标准,支持大硬盘和1.2M高密软驱。
1984年9月: Apple 发布了有512Kb 内存的Macintosh,但其他方面没有什么提高。
1984 底: Compaq开始开发IDE接口,可以以更快的速度传输数据,并被许多同行采纳,后来更进一步的EIDE推出,可以支持到528MB的驱动器。数据传输也更快。
1985: Philips和Sony合作推出CD-ROM驱动器。
1985: EGA标准推出。
1985年3月: MS-DOS 3.1、PC-DOS 3.1。这是第一个提供部分网络功能支持DOS版本。
1985年10月17日: 80386 DX推出。时钟频率到达33MHz,可寻址1GB内存。比286更多的指令。每秒6百万条指令,集成275000个晶体管。
1985年11月: Microsoft Windows发布。但在其3.0版本之全面没有得到广泛的应用。需要DOS的支持,类似苹果机的操作界面,以致被苹果控告。诉讼到1997年8月才终止。
1985 年12月: MS-DOS 3.2、PC-DOS 3.2。这是第一个支持3.5英寸磁盘的系统。但也只是支持到720KB。到3.3版本时方可支持1.44兆。
1986 年1月: Apple 发布较高性能的Macintosh。有四兆内存,和SCSI适配器。
1986 年9月: Amstrad Announced发布便宜且功能强大的计算机Amstrad PC 1512。具有CGA图形适配器、512KB内存、8086处理器20兆硬盘驱动器。采用了鼠标器和图形用户界面,面向家庭设计。
1987: Connection Machine超级计算机发布。采用并行处理,每秒钟2亿次运算。
1987: Microsoft Windows 2.0发布,比第一版要成功,但并没有多大提高。.
1987: 英国数学家Michael F. Barnsley找到图形压缩的方法。
1987: Macintosh II发布,基于Motorola 68020处理器。时钟16MHz,每秒260万条指令。有一个SCSI适配器和一个彩色适配器。
1987年4月2日: IBM推出PS/2系统。最初基于8086处理器和老的XT总线。后来过渡到80386,开始使用3.5英寸1.44MB软盘驱动器。引进了微通道技术,这一系列机型取得了巨大成功。出货量达到200万台。
1987: IBM发布VGA技术。
1987: IBM发布自己设计的微处理器8514/A。
1987年4月: MS-DOS 3.3、PC-DOS 3.3。随IBM PS/2一起发布,支持1.44MB驱动器和硬盘分区。可为硬盘分出多个逻辑驱动器。
1987年4月: Microsoft和IBM发布S/2Warp操作系统。但并未取得多大成功。
1987年8月: AD-LIB声卡发布。一个加拿大公司的产品。
1987年10月: Compaq DOS (CPQ-DOS) v3.31发布。支持的硬盘分区大于32Mb。
1988: 光计算机投入开发,用光子代替电子,可以提高计算机的处理速度。
1988: XMS标准建立。
1988: EISA标准建立。
1988 6月6日: 80386 SX为了迎合低价电脑的需求而发布。
1988年7月到8月: PC-DOS 4.0、MS-DOS 4.0。支持EMS内存。但因为存在BUG,后来又陆续推出4.01a。
1988年9月: IBM PS/20 286发布,基于80286处理器,没有使用其微通道总线。但其他机器继续使用这一总线。
1988年10月: Macintosh Iix发布。基于Motorola 68030处理器。仍使用16 MHz主频、每秒390万条指令,支持128M RAM。
1988年11月: MS-DOS 4.01、PC-DOS 4.01发布。
1989: Tim Berners-Lee 创立World Wide Web雏形,他工作于欧洲物理粒子研究所。通过超文本链接,新手也可以轻松上网浏览。这大大促进了INTERNET的发展。
1989: Phillips和Sony发布CD-I标准。
1989年1月: Macintosh SE/30 发布。基于新型68030处理器。
1989年3月: E-IDE标准确立,可以支持超过528MB的硬盘容量。可达到 33.3 MB/s 的传输速度。并被许多CD-ROM所采用。
1989年4月10日: 80486 DX发布,集成120万个晶体管。其后继型号时钟频率达到100MHz。
1989年11月: Sound Blaster Card(声卡)发布。
1990~2000
1990: SVGA标准确立。
1990年3月 : Macintosh Iifx发布,基于68030CPU,主频40MHz,使用了更快的SCSI接口。
1990年5月22日: 微软发布Windows 3.0。兼容MS-DOS模式。
1990年10月: Macintosh Classic发布,有支持到256色的显示适配器。
1990年11月: 第一代MPC (多媒体个人电脑标准)发布。处理器至少80286/12MHz,后来增加到80386SX/16 MHz ,及一个光驱,至少150 KB/sec的传输率。
1991: 发布ISA标准。
1991年5月: Sound Blaster Pro发布。
1991年6月: MS-DOS 5.0、PC-DOS 5.0。为了促进OS/2的发展,Bill Gates说:DOS5.0是DOS终结者,今后将不再花精力于此。该版本突破了640KB的基本内存限制。这个版本也标志着微软与IBM在DOS上的合作的终结。
1992: Windows NT发布,可寻址2G RAM。
1992年4月: Windows 3.1发布。
1992年6月: Sound Blaster 16 ASP发布。
1993: INTERNET开始商业化运行。
1993: 经典游戏Doom发布。
1993: Novell并购Digital Research, DR-DOS成为Novell DOS。
1993年3月22: Pentium发布。集成了300多万个晶体管。初期工作在60-66MHz。每秒钟执行1亿条指令。
1993年5月: MPC标准2发布。CD-ROM传输率要求300KB/sec。在320*240的窗口中每秒播放15帧图像。
1993年12月: MS-DOS6.0发布,包括一个硬盘压缩程DoubleSpace,,但一家小公司声称,微软剽窃了其部分技术。于是在后来的DOS6.2中,微软将其改名为:DriveSpace。后来WIN95中的DOS成为DOS7.0,WIN95OSR2中称为DOS7.10.
1994年3月7日: Intel 发布90-100 MHz Pentium处理器。
1994年9月: PC-DOS 6.3发布。
1994年10月10日: Intel 发布75 MHz Pentium处理器。
1994: Doom II 发布。开辟了PC机游戏广阔市场。
1994: Netscape 1.0 浏览器发布。
1994: Comm&Conquer(命令与征服)发布。
1995年3月27日: Intel发布120 Mhz的Pentium处理器。
19956月1日: Intel发布133 Mhz的Pentium处理器。
1995年8月23日: Windows '95 发布。大大不同于其以前的版本。完全脱离MS-DOS,但照顾用户习惯还保留了DOS形式。纯32位的多任务操作系统。该版本取得了巨大的成功。
1995年11月1日: Pentium Pro发布。主频可达200 MHz ,每秒钟完成4.4亿条指令,集成了550万个晶体管。
1995年12月: Netscape发布其.JavaScript。
1996: Quake、Civilization 2、Command& Conquer - Red Alert等一系列的着名游戏发布。
1996年1月: Netscape Navigator 2.0发布,第一个支持JavaScript的浏览器。
1996年1月4日: Intel发布150-166MHz的Pentium处理器,集成了330万个晶体管。
1996: Windows '95 OSR2发布,修复了部分BUG,扩充了部分功能。
1997: Gr和 Theft Auto、Quake 2、Blade Runner等着名游戏发布,3D图形加速卡大行其道。
1997年1月8日: Intel发布Pentium MMX。对游戏和多媒体功能进行了增强。
1997年4月: IBM的深蓝(Deep Blue)计算机,战胜人类国际象棋世界冠军卡斯帕罗夫。
1997年5月7日: Intel发布Pentium II,增加了更多的指令和更多CACHE。
1997年6月2日: Intel 发布233 MHz Pentium MMX.
1997年16日: Apple遇到严重的财务危机,微软伸出援助之手,注资1.5亿美元。条件是Apple撤消其控诉:微软模仿其视窗界面的起诉,并指出Apple也是模仿了XEROX的设计。
1998年2月 : Intel发布333 MHz Pentium II处理器。采用0.25微米技术,提高速度,减少发热量。
1998年6月25日: Microsoft发布Windows '98,一些人企图肢解微软,微软回击说这会伤害美国的国家利益。
1999年1月25日: Linux Kernel 2.2.0发布。 人们对其寄予厚望。
1999年2月22日: AMD公司发布K6-III 400MHz。有测试说其性能超过Intel P-III 。集成2300万个晶体管、socket 7结构。
再往下就是今天了,与整个人类的发展历程相比、与传统科学技术相比,计算机的历史才刚刚开始书写,我们正置身其中,感受其日新月异的变化,被计算机大潮裹挟着丝毫不得停歇。

2008年8月28日星期四

成为本地安全大师需要的五个重要步骤

 成为本地安全专家实际上并不是什么困难的事情,只要你可以对网络资源进行加密操作,指出安全政策改革的来源,并象TechRepublic社区要求的那样撰写安全方面的文章。换句话说,只要用心去写了,没有语法和拼写错误就可以了。对我来说,这并不是什么困难的事情。你只要五个步骤就可以完成这样的工作。

  1.从习惯的领域跳出来。使用你不熟悉的软件。了解新技术。我的意思并不是要你尝试不同的防病毒解决方案,而是你应该使用一些根本的不同软件。

  如果你是一名微软认证系统工程师的话,就不应该管理活动目录域,而是利用Linux和FreeBSD操作系统建立家庭网络。如果你是一个操作系统发烧友,在家里有Linux、Windows和MacOS X等多台机器,甚至还有古老的BeOS或者Amiga操作系统的话,就应该建立一个备份服务器以及一个自动记录服务器,并且从零开始建立防火墙与路由器。

  我已经做了大量这样的工作。作为学习一个新操作系统的挑战,我关注于Plan 9 分布式操作系统。正如我刚才说,如果你走出熟悉的地带,并且了解了不同的技术,就可以开始学习新的东西,已经使用了的新技术,并且会加深对系统的理解。

  2.学习一些编程技术。即使只是一点点的编程技术也可以帮助你了解更多的关于如何在整个软件体系结构的系统安全中扮演重要角色。只要多一点点就会教你更多地了解它。

  当你了解了如何为某一特定的操作系统编写驱动程序,就可以发现这个操作系统的安全缺陷。当你了解了如何编写文件系统的代码,就可以知道文件系统的设计和操作系统的特权分离事宜,这样的话,就可以拥有自己的观点。

  3.大量地阅读。首先,加入邮件列表。合适的列表包括,开放源代码社区、编程技术社区以及信息安全研究社区提供的内容。

  作为安全学习的原则。配合安全领域相关的提问,从世界上最有影响力的黑客电子邮件组BugTraq你可以获得安全方面的最新消息。此外,你也可以阅读象布鲁斯·施奈尔一类专家的安全报告。

  经常保持阅读和安全有关的好书。安全类的书籍可以让你了解不少有关安全的原理,帮助你更快得成长。

  4.经常检查你的设定。加密不等于安全,你不能一直确认防伪和加密会让系统变得更安全。我不是要你忽略知道的一切,而是应该仔细再三的检查,并对设定进行思考和分析。

  5.最后,了解自身的实际情况。不要在别人告诉你应该如何进行安全操作的时间,就无条件相信。你应该仔细考虑,慢慢分析,如果存在多种可能性的话,确认它适合实际的情况。思考的时间,要注意,什么是在他告诉你的时间可能没提到的,它的来源是哪里。每个人都有自己的目标,你要考虑自己的目标和其他的有什么不同,避免可能存在的陷阱。

  额外奉送一个建议,第六个步骤就是把我的blog加入你的列表。在不久的将来我将在TechRepublic社区信息安全的blog里提供更多的可以帮助你成为安全大师的资料。

2008年8月16日星期六

UTF-8

目录·历史
·描述
·UTF-8的衍生物
·设计UTF-8的理由
·过长的资料排列(overlong forms)、输入无效及保安的考虑
·优点及缺点
·使用UTF-8的原因
·UTF-8的编码方式
·UTF-8的特性
·UTF-8编码的缺点




UTF-8(8 位元 Universal Character Set/Unicode Transformation Format)是针对Unicode 的一种可变长度字符编码。它可以用来表示 Unicode 标准中的任何字符,而且其编码中的第一个字节仍与 ASCII 相容,使得原来处理 ASCII 字符的软件无需或只作少部份修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他储存或传送文字的应用中,优先采用的编码。
UTF-8 使用一至四个字节为每个字符编码:

128 个 US-ASCII 字符只需一个字节编码(Unicode 范围由 U+0000 至 U+007F)。
带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要二个字节编码(Unicode 范围由 U+0080 至 U+07FF)。
其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码。
其他极少使用的 Unicode 辅助平面的字符使用四字节编码。

对上述提及的第四种字符而言,UTF-8 使用四个字节来编码似乎太耗费资源了。但 UTF-8 对所有常用的字符都可以用三个字节表示,而且它的另一种选择,UTF-16编码,对前述的第四种字符同样需要四个字节来编码,所以要决定 UTF-8 或 UTF-16 哪种编码比较有效率,还要视所使用的字符的分布范围而定。不过,如果使用一些传统的压缩系统,比如 DEFLATE,则这些不同编码系统间的的差异就变得微不足道了。若顾及传统压缩算法在压缩较短文字上的效果不大,可以考虑使用 Standard Compression Scheme for Unicode(SCSU)。
因特网工程工作小组(IETF)要求所有因特网协议都必须支援 UTF-8 编码。[1] 互联网邮件联盟(IMC)建议所有电子邮件软件都支援 UTF-8编码。所有主要的电子邮件软件中,只有 Eudora 不支援 UTF-8 编码。[1]




历史

1992年初,为建立良好的字节串编码系统(byte-stream encoding)以供多字节字符集(multi-byte character sets)使用,开始了一个正式的研究。ISO/IEC 10646的初稿中有一个非必须的附录,名为UTF。当中包含了一个供32位元的字符使用的字节串编码系统。这个编码方式的性能并不令人满意,但它提出了将0-127的范围保留给ASCII以相容旧系统的概念。
1992年7月,X/Open委员会XoJIG开始寻求一个较佳的编码系统。UNIX 系统实验室(UNIX System Laboratories, USL)的Dave Prosser为此提出了一个编码系统的建议。它具备可更快速实作的特性,并引入一项新的改进。其中,7位元的ASCII符号只代表原来的意思,所有多字节序列则会包含第8位元的符号,也就是所谓的最高有效位元。
1992年8月,这个建议由IBMX/Open的代表流传到一些感兴趣的团体。与此同时,贝尔实验室Plan 9操作系统工作小组的肯·汤普逊对这编码系统作出重大的修改,让编码可以自我同步(self-synchronizing),使得不必从字串的开首读取,也能找出字符间的分界。1992年9月2日,汤普逊和Pike一起在美国新泽西州一架餐车的餐桌垫上描绘出此设计的要点。接下来的日子,Pike及汤普逊将它实现,并将这编码系统完全应用在Plan 9当中,及后他将有关成果回馈X/Open。
1993年1月25-29日的在圣地牙哥举行的USENIX会议首次正式介绍UTF-8。
自1996年起,微软的CAB(MS Cabinet)规格在UTF-8标准正式落实前就明确容许在任何地方使用UTF-8编码系统。但有关的编码器实际上从来没有实作这方面的规格。


描述

目前有好几份关于UTF-8详细规格的文件,但这些文件在定义上有些许的不同:

RFC 3629 / STD 63(2003),这份文件制定了UTF-8是标准的因特网协议元素
第四版,The Unicode Standard,§3.9-§3.10(2003)
ISO/IEC 10646-1:2000附加文件D(2000)

它们取代了以下那些被淘汰的定义:

ISO/IEC 10646-1:1993修正案2/附加文件R(1996)
第二版,The Unicode Standard,附录A(1996)
RFC 2044(1996)
RFC 2279(1998)
第三版,The Unicode Standard,§2.3(2000)及勘误表#1:UTF-8 Shortest Form(2000)
Unicode Standard 附加文件#27: Unicode 3.1(2001)

事实上,所有定义的基本原理都是相同的,它们之间最主要的不同是支援的字符范围及无效输入的处理方法。
Unicode字符的位元被分割为数个部分,并分配到UTF-8的字节串中较低的位元的位置。在U+0080的以下字符都使用内含其字符的单字节编码。这些编码正好对应7位元的ASCII字符。在其他情况,有可能需要多达4个字符组来表示一个字符。这些多字节的最高有效位元会设定成1,以防止与7位元的ASCII字符混淆,并保持标准的字节主导字串(standard byte-oriented string)运作顺利。

Unicode在范围D800-DFFF中不存在任何字符,基本多文种平面中约定了这个范围用于UTF-16扩展标识辅助平面(两个UTF-16表示一个辅助平面字符). 当然,任何编码都是可以被转换到这个范围,但在unicode中他们并不代表任何合法的值


例如,希伯来语字母 aleph (?)的Unicode代码是 U+05D0,按照以下方法改成 UTF-8:

它属于 U+0080到U+07FF区域,这个表说明它使用双字节, 110yyyyy 10zzzzzz.
十六进制 的 0x05D0换算成二进制就是 101-1101-0000.
这11位数按顺序放入"y"部分和"z"部分: 11010111 10010000.
最后结果就是双字节,用十六进制写起来就是 0xD7 0x90,这就是这个字符aleph (?)的UTF-8编码。

所以开始的128个字符(US-ASCII)只需一字节,接下来的1920个字符需要双字节编码,包括带变音符号的拉丁字母, 希腊字母, 西里尔字母, 科普特语字母, 亚美尼亚语字母, 希伯来文字母和阿拉伯字母的字符。基本多文种平面中其余的字符使用三个字节,剩余字符使用四个字节。
根据这种方式可以处理更大数量的字符。原来的规范允许长达6字节的序列,可以覆盖到31位元 (通用字符集原来的极限)。尽管如此,2003年11月UTF-8 被 RFC 3629 重新规范,只能使用原来Unicode定义的区域, U+0000到U+10FFFF。根据这些规范,以下字节值将无法出现在合法 UTF-8序列中:



UTF-8的衍生物


Windows
虽然不是标准,但许多Windows 程序(包括Windows 笔记本) 在UTF-8编码的档案的开首加入一段字节串EF BB BF。这是编码成UTF-8的Byte Order Mark U+FEFF。没有预期要处理UTF-8的文字编辑器和浏览器会会显示为ISO-8859-1字符"???"。

Java
在通常用法下,Java程序语言在通过Template:Javadoc:SE 和Template:Javadoc:SE读取和写入串的时候支持标准UTF-8。但是,Java也支持一种非标准的变体UTF-8,供对象的系列化,Java本地界面和在class文件中的嵌入常数时使用的Template:Javadoc:SE。
标准和改正的UTF-8有两个不同点。第一,空字符 (null character,U+0000)使用双字节,而不是单字节,分别是11000000 10000000。这保证了在已编码字串中没有嵌入空字节。因为C语言等语言程序中,单字节空字符是用来标志串串结尾的。当已编码字串放到这样的语言中处理,一个嵌入的空字符将把字串一刀两断。
第二个不同点是基本多文种平面之外字符的编码的方法。在标准UTF-8中,这些字符使用4字节形式编码,而在改正的UTF-8中,这些字符和UTF-16一样首先表示为代理对(surrogate pairs),然后再像CESU-8那样按照代理对分别编码。这样改正的原因更是微妙。Java中的字符为16位长,因此一些Unicode字符需要两个Java字符来表示。语言的这个性质盖过了Unicode的增补平面的要求。尽管如此,为了要保持良好的向后兼容、要改变也不容易了。这个改正的编码系统保证了一个已编码字串可以一次编为一个UTF-16码,而不是一次一个Unicode码点。 不幸的是,这也意味着UTF-8中需要4字节的字符在改正UTF-8中变成需要6字节。
因为改正的UTF-8并不是 UTF-8,所以用户在交换信息和使用互联网的时候需要特别注意不要误把改正UTF-8当成UTF-8数据。

Mac OS X
Mac OS X操作系统使用正式分解万国码(canonically decomposed Unicode),在文件系统中使用UTF-8编码进行文件命名,这做法通常被称为UTF-8-MAC。正式分解万国码中,预分解字符是被禁止使用的,必须以组合字符取代。
这种方法使分类变得非常简单,但是会搞混那些使用预分解字符为标准、组合字符用来显示特殊字符的软件。Mac系统的这种NFD数据是万国码规范化(Unicode normalization)的一种格式。而其他系统, 包括Windows和 Linux, 使用万国码规范的NFC形式,也是W3C标准使用的形式。所以NFD数据必须典型的转换成NFC才能被其他平台或者网络使用。
在此有关于此问题的讨论 Apple Q&A 1173.


设计UTF-8的理由

UTF-8的设计有以下的多字符组序列的特质:

单字节字符的最高有效位元永远为0。
多字节序列中的首个字符组的几个最高有效位元决定了序列的长度。最高有效位为110的是2字节序列,而1110的是三字节序列,如此类推。
多字节序列中其余的字节中的首两个最高有效位元为10

UTF-8的这些特质,保证了一个字符的字节序列不会包含在另一个字符的字节序列中。这确保了以字节为基础的部份字串比对(sub-string match)方法可以适用于在文字中搜寻字或词。有些比较旧的可变长度8位元编码(如Shift-JIS)没有这个特质,故字串比对的算法变得相当复杂。虽然这增加了UTF-8编码的字串的冗余,但是利多于弊。另外,资料压缩并非Unicode 的目的,所以不可混为一谈。即使在传送过程中有部份字节因错误或干扰而完全遗失,还是有可能在下一个字符的起点重新同步,令受损范围受到限制。
另一方面,由于其字节序列设计,如果一个疑似为字符串的序列被验证为UTF-8编码,那么我们可以有把握地说它是UTF-8字符串。一段两字节随机序列碰巧为合法的UTF-8而非ASCII 的机率为32分1。对于三字节序列的机率为256分3,对更长的序列的机率就更低了。


过长的资料排列(overlong forms)、输入无效及保安的考虑



优点及缺点

关于字符串长度的一个注解:
总体来说,在Unicode字符串中不可能由码点数量决定显示它所需要的长度,或者显示字符串之后在文本缓冲区中光标应该放置的位置;组合字符、变宽字体、不可打印字符和从右至左的文字都是其归因。
所以尽管在UTF-8字符串中字符数量与码点数量的关系比UTF-32更为复杂,在实际中很少会遇到有不同的情形。

总体

优点

UTF-8是ASCII的一个超集。因为一个纯ASCII字符串也是一个合法的UTF-8字符串,所以现存的ASCII文本不需要转换。为传统的扩展ASCII字符集设计的软件通常可以不经修改或很少修改就能与UTF-8一起使用。
使用标准的面向字节的排序例程对UTF-8排序将产生与基于Unicode代码点排序相同的结果。(尽管这只有有限的有用性,因为在任何特定语言或文化下都不太可能有仍可接受的文字排列顺序。)
UTF-8和UTF-16都是扩展标记语言文档的标准编码。所有其它编码都必须通过显式或文本声明来指定。[2]
任何面向字节的字符串搜索算法都可以用于UTF-8的数据(只要输入仅由完整的UTF-8字符组成)。但是,对于包含字符记数的正则表达式或其它结构必须小心。
UTF-8字符串可以由一个简单的算法可靠地识别出来。就是,一个字符串在任何其它编码中表现为合法的UTF-8的可能性很低,并随字符串长度增长而减小。举例说,字符值C0,C1,F5至FF从来没有出现。为了更好的可靠性,可以使用正则表达式来统计非法过长和替代值(可以查看W3 FAQ: Multilingual Forms上的验证UTF-8字符串的正则表达式)。


缺点

一份写得很差(并且与当前标准的版本不兼容)的UTF-8解析器可能会接受一些不同的伪UTF-8表示并将它们转换到相同的Unicode输出上。这为设计用于处理八位表示的校验例程提供了一种遗漏信息的方式。







使用UTF-8的原因

ASCII转换成UCS-2,在编码前插入一个0x0。用这些编码,会含括一些控制符,比如 " 或 &#39;&#39;&#39;&#39;/&#39;&#39;&#39;&#39;,这在UNIX和一些C函数中,将会产生严重错误。因此可以肯定,UCS-2不适合作为Unicode的外部编码,也因此诞生了UTF-8。


UTF-8的编码方式

UTF-8是UNICODE的一种变长度的编码表达方式 〈一般UNICODE为双字节(指UCS2)〉,它由Ken Thompson于1992年建立,现在已经标准化为RFC 3629。UTF-8就是以8位为单元对UCS进行编码,而UTF-8不使用大尾序和小尾序的形式,每个使用UTF-8储存的字符,除了第一个字节外,其余字节的头两个位元都是以 "10" 开始,使文字处理器能够较快地找出每个字符的开始位置。
但为了与以前的ASCII码相容 (ASCII为一个字节),因此 UTF-8 选择了使用可变长度字节来储存 Unicode:


在ASCII码的范围,用一个字节表示,超出ASCII码的范围就用字节表示,这就形成了我们上面看到的UTF-8的表示方法,这様的好处是当UNICODE文件中只有ASCII码时,储存的文件都为一个字节,所以就是普通的ASCII文件无异,读取的时候也是如此,所以能与以前的ASCII文件相容。



大于ASCII码的,就会由上面的第一字节的前几位表示该unicode字符的长度,比如110xxxxxx前三位的二进制表示告诉我们这是个 2BYTE的UNICODE字符;1110xxxx是个三位的UNICODE字符,依此类推;xxx 的位置由字符编码数的二进制表示的位填入. 越靠右的 x 具有越少的特殊意义.只用最短的那个足够表达一个字符编码数的多字节串. 注意在多字节串中, 第一个字节的开头"1"的数目就是整个串中字节的数目.。

ASCII字母继续使用1字节储存,重音文字、希腊字母或西里尔字母等使用2字节来储存,而常用的汉字就要使用3字节。辅助平面字符则使用4字节。
在UTF-8文件的开首,很多时都放置一个U+FEFF字符 (UTF-8 以 EF,BB,BF 代表),以显示这个文字档案是以UTF-8编码。


UTF-8的特性



UCS 字符 U+0000 到 U+007F (ASCII) 被编码为字节 0x00 到 0x7F (ASCII 兼容),这也意味着只包含 7 位 ASCII 字符的文件在 ASCII 和 UTF-8 两种编码方式下是一样的.
所有 >U+007F 的 UCS 字符被编码为一个多个字节的串, 每个字节都有标记位集。因此,ASCII 字节 (0x00-0x7F) 不可能作为任何其他字符的一部分。
表示非 ASCII 字符的多字节串的第一个字节总是在 0xC0 到 0xFD 的范围里,并指出这个字符包含多少个字节。多字节串的其余字节都在 0x80 到 0xBF 范围里,这使得重新同步非常容易,并使编码无国界,且很少受丢失字节的影响。
可以编入所有可能的 231个 UCS 代码
UTF-8 编码字符理论上可以最多到 6 个字节长, 然而 16 位 BMP 字符最多只用到 3 字节长。
Bigendian UCS-4 字节串的排列顺序是预定的。
字节 0xFE 和 0xFF 在 UTF-8 编码中从未用到,同时,UTF-8以字节为编码单元,它的字节顺序在所有系统中都是一様的,没有字节序的问题,也因此它实际上并不需要BOM。
与 UTF-16 或其他 Unicode 编码相比,对于不支援 Unicode 和 XML 的系统,UTF-8 更不容易造成问题。

【注】

UTF为UCS / Unicode Transformation Format“Unicode转换格式”的缩写。
UCS的中文全称为:信息技术--通用多八位编码字符集 (Universal Multi-octet Coded Character Set),由ISO/IEC 10646 标准描述。



UTF-8编码的缺点


不利于正则表达式检索
正则表达式可以进行很多英文高级的模糊检索。例如,[a-h]表示a到h间所有字母。
同样GBK编码的中文也可以这样利用正则表达式,比如在只知道一个字的读音而不知道怎么写的情况下,也可用正则表达式检索,因为GBK编码是按读音排序的。只是UTF-8不是按读音排序的,所以会对正则表达式检索造成不利影响。但是这种使用方式并未考虑中文中的破音字,因此影响不大。Unicode是按部首排序的,因此在只知道一个字的部首而不知道如何发音的情况下,UTF-8 可用正则表达式检索而GBK不行。

其他
与其他 Unicode 编码相比,特别是UTF-16,在 UTF-8 中 ASCII 字符占用的空间只有一半,可是在一些字符的 UTF-8 编码占用的空间就要多出,特别是中文、日文和韩文(CJK)这样的象形文字,所以具体因素因文档而异,但不论哪种情况,差别都不可能很明显。

2008年8月12日星期二

未来系统:Plan9

动机

到80年代中期,计算的趋势从大的集中式的分时计算向更小的个人机器(典型的如UNIX工作站) 组成的网络方向转移。人们早已对过载的和受严格管束的分时机器厌倦了,渴望转而使用小的, 自维护的系统,即使意味着计算能力上有不少损失。微型计算机变得越来越快,像那样的损失是可以弥补的,时至今日这种计算方式依然流行。

尽管个人工作站在急促发展,但是它们的某些缺点还是被忽视了。首先,它们运行的操作系统 UNIX本身是一个古老的分时系统而且很难和在它诞生之后的思想相适应。图形和网络功能被很好地加入到UNIX生存期之中,同时是很差劲地被集成进去的以及难于管理。更为重要的是早期集中在拥有私人机器从而让计算机网络像老的单一分时系统一样无缝地提供服务变得困难了。分时把管理和分期偿还投资和资源集中化了;个人计算分散了,民主化了以及从根本上扩大了管理问题。选择一个老的分时操作系统来运行这些个人机器使得平滑地一起绑定一些东西变得困难了。

开始于20世纪80年代后期 Plan 9 作为一个尝试通过两种方法实现:构建一个被集中管理的和好的价格性能比--通过使用便宜的现代微型计算机作为它的计算元素--的系统。意图是要构建一个脱离工作站的分时系统,但是以新颖的方式实现。不同的计算机处理不同的任务(tasks):在人们的办公室里的小的便宜的机器作为终端,提供对大的,集中的共享资源的如计算服务器和文件服务器的访问能力。对于集中的机器,正在来临的共享存储多处理器(译者注:一种多处理器的方案,可参考<;高等计算机体系结构>;;一书,徐志伟&;黄铠,机械工业出版社)高潮好像是一种明显的候选方案。这里的想法很像剑桥分布式系统(CambridgeDistributed System)所采用的[NeHe82]。早期的口号是要构建一个脱离许多小系统的UNIX,而不是一个脱离许多小UNIX的系统。

UNIX的问题是太深难于修改,但是它的某些思想还是可以继续发展的。最好的一个就是它的文件系统的使用,用一致的方法命名和访问资源,甚至那些如设备,不再传统地看作文件。对于Plan 9,我们采用了这个思想,设计了一个称作9p的网络级协议能让机器访问远端系统上的文件。在此之上,我们构建了一个命名系统,它让人们和它们的计算代理建立网络中资源的个性化视图。这就是Plan 9第一个开始看起来不同的地方:一个Plan 9用户构建一个私人的计算环境还可以在任何想要的地方重新创建,而不是在一个私人机器上做所有计算。很快就变得清楚了,这个模型比我们预见的还要更丰富,像每个进程的名字空间和类文件系统资源这样的想法被扩展到整个系统--到进程,图形,甚至网络本身。

到1989年,系统已经足够稳定,以至于我们当中的一些人把它用作我们的高级(exclusive)计算环境。这就意味着带来我们已在UNIX上使用的许多服务和应用。我们借此机会重新思考了许多问题, 而不仅仅是驻留在内核中的,我们认为UNIX被很差地访问。Plan 9有新的编译程序,程序设计语言, 程序库,窗口系统和许多新的应用程序。许多旧的工具已不再使用,而这些一起带来的应用程序则被改进或重写。

为什么会如此的全部包含呢?因为操作系统,库和应用程序之间的差别对操作系统研究者是重要的,但是用户却对它没有兴趣。重要的是清晰的功能性。通过建立一个全新的系统,我们能去解决我们认为应当要解决的问题。例如,内核中没有实际的'tty 驱动程序';因为那是窗口系统的职责。在当今世界,多家销售商和多种体系结构的计算机这一事实是关键的,而通常的编译程序和工具假定程序是被建立在本地环境运行的;我们有必要重新思考这个问题。然而最重要的是系统的其余部分是它所提供的计算环境。探索一个运行老的UNIX系统更有效率的方式是吃力不讨好的;我们对由底层系统体系启示得来的新想法是否能够促进工作效率的提高更感兴趣。因此,Plan 9为运行POSIX 命令提供一仿真环境,它是系统的死水(backwater)。系统软件的绝大部分都是在本地的Plan 9 环境中开发出来的。

拥有一个全新的系统有几个好处。首先,我们的实验室由一个制造试验用外设板卡的历史。为了使写驱动程序更简单些,我们想要一个原始形式可得的系统(不再向UNIX保证,即使在它所诞生的实验室)。其次,我们想重新发布我们的作品,这就意味着软件必须本地化生成。例如我们已经在我们的系统上使用了某些销售商的C编译程序,但是即使我们克服了交叉编译的问题,我们还会有重新发布最终软件的困难。

本篇论文是对Plan 9系统的概述。它讨论了系统结构--从最底层的构件模块到用户可见的计算环境。也作为对Plan 9程序员手册的其它部分的导论,本论文和它们放在一起。关于论文中相关主题的更多细节可以在手册中的其它地方找到。

设计

系统的视图构建在三个原理的基础上。第一,资源像层次式文件系统中的文件一样被命名和访问。其次,有一个名叫9P的协议用于访问这些资源。第三,不同服务提供的不相交的层次被连接进单一的私有的层次式文件名字空间。Plan 9的不同一般的特性来源于对这三个原则的始终如一的和主动的应用。

大型的Plan 9的安装有许多通过网络连接在一起的计算机,每一台提供一个具体的服务级别。共享型多处理器服务器提供计算周期;其它大机器提供文件存储。这些机器放置在带空调机的房间,且用高性能的网络连接起来。低带宽网络如以太网(Ethernet)或ISDN把这些服务器连接到办公室和家里的工作站或PC,在Plan 9术语中叫终端。图1显示了这样的布局安排。


计算的现代方式是为每一个用户提供一台专用的工作站或者PC。Plan 9的方法是不同的。各种不同的机器都有提供访问网络资源的屏幕,键盘和鼠标,因此它们功能上同连接到老式的分时系统的终端在习惯上是相同的。然而,当某人使用系统时,终端从术语上讲被用户独自占有。作为自定义硬件的替代,Plan 9给予用户自定义自己系统视图的能力,这些能力由软件提供。定制是通过给网络中公共可见的资源以局部的私有的名字来完成的。Plan 9 提供这样一个机制:用全局可访问资源的局部名字集成一个公共空间的私有视图。因为网络的最重要资源是文件,这个视图的模型是面向文件的。

客户的本地名字空间提供一个定制网络的用户视图的方法。网络中可以获得的服务都导出文件层次结构。这些对用户重要的东西被一起集成到用户的名字空间;那些没有直接影响的就被忽略了。这是一个来自 "单一全局名字空间"思想的不同的使用风格。在Plan 9中,有众所周知的名字用于服务和用于由这些服务导出的文件的单独名字,但是视图却是完全本地的。作为一个类比,考虑短语'我的房子'和说话人的家的精确地址之间的区别。后者可以被任何人使用,但前者更容易说和讲得通。还可以依赖于谁说它而改变含义,而且不会导致混淆。类似的,在Plan 9中 名字/dev/cons总是指用户的终端,而/bin/date指要运行的date命令的恰当版本,但是这些名字所代表的文件取决于执行date命令时的环境例如机器的体系结构。 Plan 9由遵循全局可理解的惯例的本地名字空间;惯例是:在局部名字面前保证健全的行为。

9P协议是用一组事务(transactions)的集合建构成的:从一个客户发送一个请求到(本地或远程) 服务器,然后返回结果。9P控制文件系统,不仅仅是文件:它包含解析(resolve)文件名字的过程和转换由服务器提供的文件系统上的名字层次结构。另一方面,客户名字空间仅由客户系统处理, 不在也不和服务器一起处理,和Sprite[OCDNW88]这样的系统不一样。而且文件的访问是在字节的水平上,而不是块,这就把9P和NFS及RFS这样的协议区分开来。Welch 写的一篇文章比较了Sprite, NFS和Plan 9的网络文件系统结构[Welc94]。

此方法用传统文件设计的,但是可以被扩展到许多其它资源。Plan 9的导出文件层次的服务包括 I/O设备,备份服务,窗口系统,网络接口和许多其它的东西。一个例子就是进程文件系统,/proc, 它提供一个干净的方法来监测和控制运行的进程。Precursor系统有一个相似的思想[Kill84],但是 Plan 9把文件隐喻推进的更深一点[PPTTW93]。文件系统模型是容易理解的,不管是系统构件者还是一般用户,因此表示类文件(file-like)接口的服务是容易构造的,易于理解的和易于使用的。 为了保护命名和访问本地和远程文件,采用了向上兼容(agreed-upon)规则,因此这种方式构建服务是为分布系统的准备性工作(ready-made)。(这与'面向对象模型'不同,在那里这些问题必须重新思考(faced anew) 对象(object)的每一个类(class)) 以下分节示例了正在实践中的这些思想。

命令级视图

Plan 9被打算从带有一个运行窗口系统的屏幕的机器上使用。它没有在UNIX意义上的'teletype'的概念。裸机系统的键盘处理是基本的,但是一旦运行了窗口系统,8½; [Pike91] ,文本就可以从弹出式菜单中的剪和贴操作来编辑,在窗口之间拷贝,等等。8½; 允许从过去的输入行编辑文本,不仅是当前输入行。8½; 的文本编辑能力强大到可以替换特殊特征如shell的历史,分页和滚动以及邮件编辑器。8½; 窗口系统不支持光标访问,除非一个为了简化连接到传统系统的终端模拟器,在Plan 9中没有光标访问式的软件。

每一个窗口在一个单独的名字空间中创建。对一个窗口中的名字空间的调整不会影响其它窗口或程序,使得对名字空间的局部修改的试验变得安全,例如当调试时从dump文件系统中代替文件。一旦调试完毕,窗口就可以被删除,所有试验机构的遗迹全部消失。应用到每一窗口拥有的私有空间的相似参数用于环境变量, 说明(和UNIX的信号相似),等等。

每一个窗口被创建来运行一个应用程序,例如shell,带有连接到窗口的可编辑文本的标准I/O。每一个窗口还有一个私有位图以及通过向这样的文件/dev/mouse,/devbitblt和/dev/cons(类似于UNIX的/dev/tty) 来多工访问键盘,鼠标和其它图形资源。这些文件由8½; 提供,它被实现成一个文件服务器。不像X窗口系统,那里一个新的应用程序要创建一个新的窗口在其中运行,一个8½; 图形应用程序通常运行在它所启动的窗口里。为一个应用程序创建一个新的窗口时可能的和有效的,但那不是系统的风格。再次和X(窗口系统)对比,在那里一个远程应用程序创建一个对X服务器的网络调用来启动运行,一个远程的8½; 应用程序为窗口察看通常在/dev目录下的mouse,bitblt和 cons文件;它不知道文件是否在本地。它为了控制窗口仅仅读和写它们;网络连接已经存在且是多工的。

预期的使用方式是诸如在终端上的窗口系统和文本编辑的交互式应用程序和运行计算-或远程服务器上文件密集(file-intensive)的应用程序。不同的窗口可能通过不同的网络运行不同的程序,但是通过让名字空间在所有窗口中等价,这是透明的:无论计算在何时执行,用相同的名字都可以获得相同的命令和资源。

Plan 9的命令集合和UNIX的命令集合是相似的。命令分成概括性的几个类别。有些是用于旧的作业的新程序:像ls,cat和who这样的程序保持相同的名字和功能,但是新的,简化了的实现。例如who命令是一个 shell脚本(script),而ps命令只有95行C语言代码。某些命令和它的UNIX祖先那里基本上是相同的:awk, troff和其它已经被转换成ANSI C的和扩充成处理Unicode,但仍然是相似的工具。某些就的事务是用完全新的程序:shell的rc文件,文本编辑程序sam,调试程序acid,以及其它用相似作用的程序替换了更为知名的 UNIX工具。最后,大约有一半的命令是新的。

兼容性不是系统的一个要求。只要老的命令或说明看上去足够好,我们就保留它,否则我们就替换它。

文件服务器

中央文件服务器存储永久文件,使用9P协议把它们导出成文件层次结构并呈现给网络。服务器是一个独立(stand-alone)的系统,只可以通过网络访问,被设计成只把它的一件事情做好即可。它不运行用户进程,只运行固定的一套被编译进引导图像的例程(routines)。服务器导出的主要层次结构(多于一组磁盘或单独的文件系统)是一棵单一的树,把文件表示在许多磁盘上。这个层次结构被广泛范围内的许多用户通过不同的网络共享。服务器导出的其它文件树包括专用的系统如临时存储和下面就要解释的一个备份服务。

文件服务器有三个存储级别。我们安装的系统中的中央服务器有大约100MB的内存缓冲,27GB的磁盘空间,还有在一个WORM点唱柜中350GB的存储容量。磁盘是WORM的高速缓冲,而内存是磁盘的一个高速缓冲;每一个都比它所缓冲的级别更快,要处理的数据流量按顺序增加。文件系统中可寻址的数据可以比磁盘的大小还要大,因为它们仅是一个高速缓冲;我们的主文件服务器大约有40GB的活动存储量。

文件服务器的最不一般的特征是使用一个WORM设备来用作稳定存储。每天早上5点钟自动发生一次文件系统的转储dump。文件系统被冻结,所有自最近一次转储(dump)以来被修改的块被排列成队列写入 WORM中。一旦块被排队,服务就被恢复,转储的文件系统的只读的根(root)出现在所有已发生的转储层次中,且以它的日期命名。例如,目录/n/dump/1995/0315是文件系统图像的一个根目录,和出现在1995年3月15日早上的一样。要花几分钟时间来排队这些块,但是拷贝块到WORM中的进程运行后台,可能要花好几个小时。

转储的文件系统有两种用途。第一种是用户自己使用,它们可以直接浏览转储文件系统,把当中的几个关连(attach)到它们自己的名字空间。例如,为了追踪一个错误,直接从三个月以前尝试编译程序或者把一个程序和昨天的库连接。用所有文件的每日快照,那么查找什么时候一个特殊的改变发生或一个特别的日子发生了什么改变这样的事是容易的。在了解文件可以用一个拷贝命令收回的条件下,人们可以自由地对文件做大的冒险性的改变。没有备份这样的系统;相反,因为转储是在文件名字空间中,备份问题可以诸如cp,ls,grep和diff这样的标准工具来解决。

其它的(很少)使用是完全系统备份。如果发生灾难,通过清除磁盘高速缓冲和把活动文件系统的根设置为转储的文件系统的根,这样就可以从任何转储来初始化活动文件系统。尽管容易做,还是不能轻率的完成:除了丢失了转储后所做的任何改变,还会导致系统速度很低。高速缓冲必须从WORM重新装入,它比磁盘慢的多。文件系统要花好几天重新装入工作集(working set),重新获得它的全部性能。

转储中的文件的访问权限和转储生成时是一样的。普通的实用程序有正常权限,在转储中没有特殊的处理。然而,转储文件系统是只读的,这就意味着转储中的文件的无论权限位如何都不能被写;实际上,既然目录是只读结构的一部分,甚至权限都不能被改变。

一旦一个文件被写入WORM中,它就不能被删除,因此我们的用户从来不会看到“请清除你的文件”这样的消息,也没有df命令。我们把WORM柜看作一个无限的资源。只有一个问题就是花多长时间就会写满数据。我们的WORM已经为一个大约50个用户的社团服务了五年,吸收每日的转储,耗费了总量的65%的存储空间。那时,制造商已经改进了技术,把每一个磁盘的容量翻倍(doubling)。如果我们打算升级成新的介质,我们就会有比当初的空磁盘更多的空闲空间。技术已经创造了比我们所使用的更快的存储设备。

不寻常的文件服务器

Plan 9的特征表现在有许多这样的服务器:它们向不一般的服务提供一个类文件(file-like)的界面。许多都是由用户级进程实现的,尽管对于它们的客户而言差别是不重要的;一个服务是由内核,一个用户进程还是一个远程服务器来提供和服务的使用方式是不相关的。有许多这样的服务器;本节我们介绍三个代表性的服务器。

Plan 9种可能最引人注目的文件服务器是8½; ,即窗口系统。它在别 的地方[Pike91]有详细的讨论,但是此处值得给一个简要的解释。8½; 提 供两个接口:给终端旁的用户,它提供和多窗口交互的传统风格,每一个都运行一个应用程序,都由 鼠标和键盘控制。给客户程序,视图也是相当传统的:运行在一个窗口中的程序看到/dev目录下的一 些文件,如 mouse,screen 和cons。想要把文本显示到它们对应窗口的程序向/dev/cons中写;读鼠 标的话,则读 /dev/mouse。以Plan 9的方式,位映射图形是这样实现的:提供一个文件 /dev/bitblt, 客户程序把经过编码的消息写到执行图形运算的程序如bitblt(RasterOp)。所不平常的是这是如何 完成的:8½; 是一个文件服务器,用/dev目录下的文件向运行在每一个窗口 中的客户提供服务。虽然每一个窗口看上去和它的客户一样,但是每一个窗口拥有/dev目录下的不同的 一组文件。8½; 通过服务多组文件来多工它的客户对终端资源的访问。通过 一个不同的文件组为每一个客户给定一个私有名字空间,这些文件组的行为和在所有其它窗口 中一样。这样的结构由许多优点。其中之一就是为相同的文件,用于它自己的实现所需要的-它多工自 己的界面-因此它可以运行,急救,把自己作为一个客户。另外,考虑 UNIX 中/dev/tty的实现,它要 求在内核中有特殊的代码把open 调用重新定向到适当的设备。相反,在 8½; 中,等价的服务自动地实现:它把/dev/cons作为基本的功能;决没有什么其它要做的。当程序象想从 键盘上读时,它打开/dev/cons,但它是一个私有文件,不是一个有特殊属性的共享文件。还有,局部 名字空间让这成为可能;它们内部的文件一致性的惯例让这变得自然。

由于8½; 的设计使得它由一个统一的特征成为可能。因为它被实现成为 一个文件服务器,它有推迟对一个具体窗口的读请求做出回答的权力。这个行为由键盘上的一个保留键 触发。触发一次对来自窗口的客户读请求的挂起;再一次触发就让正常的读继续进行,它接受任何已经 准备好的文本,一次一行。这就允许用户在引用程序得到文本之前就可以在屏幕上编辑多行输入文本, 避免了需要调用一个特别的编辑程序来准备象邮件消息这样的文本。一个相关的性质是,读直接 地从显示器上的文本定义的数据结构得到回应:文本可以被一直编辑直到它的最后新行符让文本的 预备行由客户可读为止。甚至即使到行已读入,客户要读的文本还可以被改变。例如,输入以下 命令给shell后
% make
rm *
,用户可以在make完成之前的任何时候会退过最后的新行符,延迟rm命令的执行,或者甚至在 rm之前用鼠标点击,输入另一个命令先执行。

Plan 9中没有ftp命令。相反,一个叫ftpfs的用户级文件服务器向FTP站点拨号,代表用户登录,用FTP 协议检查远程目录中的文件。对于本地用户而言,它提供一个文件层次结构,关连到本地名字空间中的/n/ftp,镜像了FTP站点的内容。也就是说,它把FTP协议转换成9P协议来提供Plan 9访问FTP站点的能力。实现是复杂而微妙的;出于效率ftpfs必须做一些 复杂的缓冲和用启发式方法来解码(decode)目录信息。但是结果是值得的:所有本地文件 管理工具诸如cp,grep,diff当然还有ls对于FTP服务提供的的文件就像它们是本地文件一样。其它系统如Jade和Prospero已经开拓出一些机会[Rao81,Neu92],但是由于本地名字空间和9P 协议实现的简洁性,比起其它环境,这个方法更自然地适合Plan 9。

一个名叫exportfs的用户进程把它自己所有的名字空间的一部分变为其它进程可获得的 ,方法是把9P请求转换成对Plan 9内核的系统调用。它所导出的文件层次结构可能包含来自 多个服务器的文件。Exportfs 通常由本地程序启动作为远程服务器运行,要么是import,要么是cpu。Import创建一个对远程机器的网络调用,在远程机器上启动exportfs,然后把它的9P连接(connection)关联(attache)到本地名字空间。例如,
import helix /net
让Helix的网络接口在本地/net目录中可见。Helix是一个有许多网络接口的中央服务器,因此这就允许有一个网络的某台机器可以访问到任何Helix的网络。这样一个导出之后,本地机器可以创建连接到Helix的任一网络的调用。另一个例子是
import helix /proc
,它让Helix的进程在本地/proc目录中可见,允许本地的调试程序检查远程进程。

cpu命令把本地终端连接到一个远程CPU服务器。它以和import相反的方向工作:调用服务器之后,它启动一个本地的exportfs进程,把它挂接到一个进城的本地名字空间中,典型的是服务器上的一个新创建的shell。然后它重新安排名字空间让本地设备文件(如那些由终端的窗口系统所服务的设备) 在服务器的/dev目录中可见。运行一个CPU命令的效果就是在一台快速的机器上启动shell,一个模拟本地名字空间的更紧密地耦合到文件服务器的shell。所有本地设备文件都是远程地可见的,因此远程应用程序具有完全访问本地服务的能力,例如位映射图形,/dev/cons等等。这和rlogin不一样,它(rlogin) 不会在远程系统上重新生成本地名字空间,而且和NFS上的文件共享不一样,NFS可以获得一部分对等的名字空间但不是对本地硬件设备,远程文件和远程CPU资源访问的复合。CPU命令是一个单一地透明机制。比如,在一个正在运行CPU命令的窗口中启动一个窗口系统是适当的;所有已经创建的窗口自动地启动CPU 服务器上的进程。

配置能力和管理

Plan 9中组件(components)的统一互连使得以多种方式配置Plan 9的安装成为可能。一个单独的膝上型PC可以作为一个单独的(stand-alone)Plan 9系统;另一个极端是我们的安装有中央的多处理器CPU服务器和文件服务器以及许多终端(从小的PC到高端图形工作站)。这样大的安装最好地展示了Plan 9是如何工作的。

系统软件是可移植的而且同样的操作系统运行在所有硬件上。除了系统的性能,系统的外观对 SGI工作站和一台膝上型电脑是一样的。既然计算和文件服务被集中了,而且终端没有永久文件存储, 所有终端功能上是相同的。 像这种方式,Plan 9 有一个老的分时系统的好的特点,即用户可以坐在任何机器面前而且看到的是相同的系统。像现代工作站的一致性,机器倾向于被个人占有,它们在机器的本地硬盘上存储私人信息来定制它们的机器。尽管系统本身可以这样使用,但是我们拒绝这种使用方式。在我们的研究组里,我们的实验室有许多可以公共使用的机器---一个终端室,用户可以坐在任何一个终端面前工作。

中央文件服务器不仅集中了文件,而且包括它们的管理和维护。实际上,一个服务器是主服务器 ,处理所有系统文件;其它服务器提供额外的存储或者用于调试和其它特殊用法,但是系统文件驻留在一台机器上。这就意味每一个程序对于每一种体系结构有唯一的二进制副本,因此安装更新(updates) 和排除错误(bug fixes)的价值不大。还有一个单一的用户数据库;没有必要去同步不同的/etc/passwd 文件(即让/etc/passwd文件尽快保持相同,译者注)。另一方面,对于一个中央服务器的依赖并不一个安装的大小。

集中式文件服务的另一个强大能力的另一个例子Plan 9管理网络信息的方式。在中央服务器上有一个目录/lib/ndb,它包含所有管理本地以太网和其它网络的必要的信息。所有的机器使用相同的数据库和网络对话;没有必要去管理一个分布式命名系统或者保持并行的文件都是新的。为了在本地以太网上安装一个新的机器,选择一个名字和IP地址,然后把这些加入到/lib/ndb目录下的单个文件中;安装中的所有机器可以立即和它对话。为了启动运行,把机器加入到网络中,打开机器然后使用BOOTP和TFTP协议装入核心。其它的一切都是自动完成的。

最后,自动的转储文件系统根据维护它们的系统的需要释放所有用户的空间,然而提供一个方便的访问备份文件系统的方法--不需要磁带,特殊命令或者重要支持的复杂情况。夸大这种服务提供的工作方式的改进是困难的。

Plan 9可以运行在许多硬件上,不限制如何设置一个安装。在我们的实验室,我们选择使用中央服务器因为它们让投资和管理可以分期偿还。这是一个好的决定的标志就是我们的便宜的终端已经适宜地工作了大约5年时间,比那些必须提供完整的计算环境的工作站的时间长的多。然而,我们的确升级过中央的机器,因此甚至旧的Plan 9终端可以获得的计算能力也能及时的改进。通过避免对终端的正常升级,节省的钱被花在最新的,最快的多处理器服务器上。我们估计这个成本只花了联网的工作站的一半,却提供了对更强大的机器的通常使用(general access)。

C 语言程序设计

Plan 9的实用程序使用了好几种语言写成。一些是shell(rc)[Duff90]的脚本(script),有一小部分是用新型的称为Alef[Wint95]的类似C的并行编程语言写成,在下面有介绍。不过,绝大多数还是用 ANSI C[ANSIC]的方言(dialect)版本写成。这些程序中绝大多数是全新的,但是有一些是从我们的研究用的UNIX系统[UNIX85]的前标准C代码。这些已经被升级到ANSI C,出于移植和干静又重写了一遍。

Plan 9的C语言有一些小的扩充和几个主要的限制,在[Pike95]有所介绍。最重要的限制是编译器要求所有函数定义有ANSI的原型(prototype),而且所有的函数调用出现在函数原型声明的作用域。作为一个文体规则,原型的声明放在一个被所有调用那个函数的头文件中。每一个系统库有一个关联的头文件,它定义了那个库中的所有函数。例如,标准的Plan 9库被称为libc,所以所有C源代码文件包含。这些规则保证所有函数被调用时带有期望类型的参数--对于ANSI C之前的C代码则不是这样的。

另一个限制是C编译器只接受ANSI要求的预处理程序制导的子集。主要的省略是#if,因为我们认为这是从不必要的而且经常混淆。同样,它的作用可以通过其它的方法更好的得到。例如,使用一个#if在编译时触发一个特征,它可以被写成正规的if语句,取决于编译时常量卷和为了释放目标码的固定代码省略量。(此句较难译,望专家指教)

条件编译甚至是#ifdef在Plan 9中也是很少使用的。系统中唯一的依赖于体系结构的 #ifdefs是图形库中的低层例程。相反,我们避免这样的依赖性,或者当必要时把它们放入单独的源文件或库中。除了使代码难于阅读以外,#ifdefs让知道什么源码被编译进库或者由它们保护的源代码是否会正常的编译和工作。它使得维护软件更难。

标准的Plan 9库有许多和ANSI C及POSIX[POSIX]重叠,但是适合Plan 9的目标和实现时是分开的。当一个函数的语义改变时,我们也改变名称。例如,相对于UNIX的creat, Plan 9有一个create函数它带有三个参数,原来的两个加上第三个---和open的第二个参数一样,定义了返回的文件描述符被打开来读,写或者读写。9P实现的创新方式促成了这个设计,但是它也简化了create的通常使用来初始化临时文件。

另一个不同于ANSI C的是Plan 9使用称为Unicode [ISO 10646,Unicode] 16位字符集。尽管我们避免了完全国际化的缺点,Plan 9 通过它的所有软件统一了对所有主要语言的表示。为了简化在程序之间文本的交换,字符使用了我们设计的编码方法打包成字节流,这个方法称为UTF-8,现在已经变成一个被接受的标准[FSSUTF]。它有几个具有诱惑力的特点,字节顺序无关性,和ASCII码向后兼容以及易于实现。


把已经存在的软件转换为大字符集的会有许多问题,这种大字符集的编码用可变数目的字节来表示字符。ANSIC提到过这些问题但是并没有完全解决。它不选择一个字符集的编码,也不定义所有必要的I/O库例程。更何况,它的函数定义有工程上的问题。既然表准遗留了太多未解决的问题,我们就决定构建我们的界面。另有一篇专题论文讨论细节[Pike93]。

小规模(class)的Plan 9程序不遵循本届所讨论的惯例。由一些来自UNIX社团维护的程序被收入系统; tex就是一个代表性的例子。为了避免每次重新移植这些程序就要发行一个新版本,我们构建了一个移植(porting)环境,称为ANSI C /POSIX环境,或APE[Tric95]。APE有独立的包含文件;库和命令组成,尽可能地和严格的ANSI C和基本的POSIX 规范一致。为了移植基于网络的软件如X-Windows,对这些规范增加一些扩充是必要的,就像BSD的联网功能。

可移植性和编译

Plan 9可以移植到许多处理器结构上。在单一的计算会晤期(Session)内,使用好几种体系结构是普遍的:窗口系统可能运行在一个连接到基于MIPS的CPU服务器上的Intel处理器,此服务器和文件主留在 SPARC系统上。为了达到异构透明性,必须有程序间交换数据所需要的协议;为了直接的维护软件,必须有跨平台编译的协议。

为了避免字节顺序问题,数据以文本形式在程序间传送任何时候都是可行的。尽管有时数据总量高到需要二进制形式,这样的数据用多字节值的预定义编码来作为字节流传送。在很少情况下,格式复杂到要用数据结构定义,此结构从不作为一个单元传送;相反,它先被拆分成单独的域,再编码成顺序字节流,最后由接受器重新汇编。这些协议影响很多数据,从内核到应用程序状态信息和由编译器生成的中间目标文件。

包括核心在内的程序常用文件系统接口表示它们的数据,这个借口是继承性的可移植访问机制。例如系统时钟由在文件/dev/time中的十进制数表示;time库函数(没有time系统调用)读文件然后转换成二进制形式。类似的,和把一个应用进程的状态编码到私有存储中的一些标志和为中不一样,核心把文本字符串表示在一个叫status的文件中,status文件在和每个进程关联的/proc目录。Plan 9的ps命令是简单的:它经过某些简单的重新格式化后打印想要的文件的状态信息;在输入下面的命令以后 import helix /proc 一个本地的ps命令给出Helix进程的状态报表。

每一个支持的体系结构都有相应的编译程序和装入程序。C和]Alef编译程序生成的中间文件是经过可移植编码的;内容相对目标结构是统一的,但是文件格式是独立于编译处理器类型的。当给定体系结构的编译程序在另一种处理器类型上编译时,在新的处理器上编译一个程序,生成的中间文件和原处理器上生成的文件是相同的。从编译程序的角度看,每一次编译都是交叉编译(cross-compilation)。(交叉编译:在一种处理器上为编译另一种体系结构的可执行文件而进行的编译-译者注。)

尽管每一种体系结构的装入程序只接受由对应的编译程序生成的中间文件,这种中间文件可以在另一种类型的处理器上编译得到。例如,在486上运行MIPS编译器,然后用SPARC上的MIPS装入程序生成MIPS可执行文件是可能的,

因为Plan 9可以运行在许多体系结构上,即使在单机安装中,在单一的源代码树种区别编译程序和中间名字简化了多体系结构的开发。每一种体系结构的编译程序和装入程序被统一命名;系统里没有CC命令(CC:c语言编译程序-译者注)。

名称通过和目标体系结构相关联的编码字母的连接而得到,还和编译程序及装入程序的名字有关。例如,字母‘s’是Intel X86处理器的编码字母;相应的编译程序叫8c;Alef编译程序称为为8al,而装入程序称为8l。类似的,编译程序的中间文件名称为。8而不是.O后缀。

Plan 9的构造程序叫mk,一个和make相对的程序,它从环境变量$cputype和$objtype读出当前的和目标的体系结构名称。默认的,当前处理器即为目标处理器,但是可以设置$objtype的值为另一个体系结构,让mk进行交叉构造:

%objtype = sparc mk

为sparc体系结构构造一个程序(不管执行的处理器为什么类型)。$objtype变量的值选择一个体系结构相关的变量定义文件,此文件把构造配置成使用适当的编译程序和装入程序。虽然此方法简单,但这个技术在实践中工作的很好:Plan 9中的所有应用程序都从单一源代码树构造,以并行而无冲突地构造不同体系结构的应用程序是可能的。

并行程序设计

Plan 9对并行程序设计的支持有两个方面。首先,核心提供一个简单的进程模型以及一些用于同步和共享而仔细设计的系统调用。第二,一个新的称为Alef的并行程序设计语言支持协同程序设计。尽管用C写并行程序是可能的,但是Alef是并行语言的当然选择

在新式操作系统领域中有一个趋势,就是实现两极进程:普通的Unix方式的进程和轻量级内核线程。相反,Plan 9一个进程级别,但是能够很好地控制一个进程的资源的共享(这些资源如内存储器和文件描述符)。单一级别的进程在Plan 9中之所以是可行的,因为核心有一个有效的系统调用接口和低开销的进程创建和调度方法。

并行程序有三个基本的要求:进程间共享资源的管理,一个调度接口和一个使用自旋锁(spin locks)的细粒度(fine-grain)的进程同步机制。在Plan 9上,新的进程用rfork系统调用创建。Rfork使用一个参数和一个向量(它指定父进程的哪一个资源应被共享,复制,或在子进程中创建新的)。Rfork控制的资源包含名字空间,环境,文件描述符表,内存段和说明(对Unix信号的Plan 9模拟)。其中一位控制rfork调用是否创建新进程;如果此位关闭,最终对资源的修改发生在进行调用时。例如,一个进程调用rfork(RFNAMEG)把它的名字空间和父进程的名字空间分开。Alef使用一个细粒度的fork,其中所有的资源在(包括内存储器)在父子进程间共享,和许多系统中创建一个内核线程相似。

Rfork的使用方式是多种多样的说明了rfork是合适的模型。和fork过程的通常使用不同很难发现两个使用rfork的调用有相同的位集合;程序用它创建许多不同形式的共享和资源分配。仅有两类进程的系统-正规进程和线程-不能处理这样的变化。

共享内存有两种方式。第一,rfork的一个标志使得父进程的所有内存段和子进程共享(除了栈,它是写时复制的)。可选地,内存的一个新段可用segattach系统调用接上;这样的段将总被父子进程共享。

Rendezvous系统调用提供进程同步的方法。Alef用它实现通信通道,排队锁,多个读写锁和睡眠唤醒机制。Rendezvous使用两个参数:一个标记和一个值。当一个进程调用带一个标记的rendezvous时,它一直睡眠到另一个进程产生一个匹配的标记。如果一对标记匹配,那么值就在两个进程间交换且两个rendzevous调用都返回。此原语已经足够实现全部的同步过程。

最后,在用户级的体系结构相关库提供自旋锁。大多数处理器提供可以用来实现锁的原子的测试设置指令。一个著名的例外是MIPS R3000,因此SGI Power系列多处理器在总线上有特殊的锁硬件。用户进程通过使用segattach系统调用访问锁硬件,这个调用把硬件锁的页照应到它们的地址空间。

在系统调用中的Plan 9进程无论它的优先级怎样都会阻塞。这就是说当一个程序希望从没有阻塞整个计算的慢速设备上读时,它必须为读创建一个进程。方法是启动一个辅助进程通过共享内存或一个管道来进行I/O和传递对主程序的反应。这听起来很麻烦而实际上很容易且效率很好;事实上,大多数Plan 9交互程序都是作为多进程程序运行的,即使是用C写的相对简单的文本编辑程序sam[Pike87]也是如此。

Plan 9中内核对并行程序设计的支持有几百行可移植代码;几个简单的原语使问题可以干静的在用户级处理。尽管原语用C工作的很好,但是在Alef中是特别有意义的。从属的I/O进程的创建和管理可以用几行的Alef写成,为任意进程间的多工数据流的一致方法提供基础。而且在语言中实现而不是在内核中为所有设备间保证一致的语义以及提供一个更通用的多工原语。把它和Unix中的select系统调用相比较:select仅用在设备的优先集合中,确立了内核多进程程序设计的风格,但是未扩展到网络,它还难于实现和使用。

Plan 9中并行程序设计重要的另一个原因是多线程的用户级文件服务器是实现服务的更好的方法。这样的服务器的例子包括程序设计环境Acme[Pike94],名字空间导出工具exportfs[PPTTW93],HTTP守护程序和网络名字服务器,和DNS[Prwi93]。像Acme这样复杂的应用程序证明精心的操作系统支持可以降低写多线程应用程序的难度,不用把线程和同步原语移动到内核中。

名字空间的实现

用户进程用三个系统调用构建名字空间:mount,bind和unmount。mount系统调用把一个文件服务器生成的树添加到当前名字空间。在调用mount之前,客户(通过外部方法)请求一个到服务器的连接,用一个可以被读写用来传递9p消息的文件描述符的形式实现请求。那个文件描述符表示一个管道或网络连接。

Mount系统调用把一个新的层次添加到现存的名字空间。另一方面,bind系统调用在名字空间的另一点上复制现存名字空间的一部分。Unmount系统调用可以让组成(名字空间的)部分被删除。

使用bind或者mount,多个目录可以在名字空间的一个点上建栈。用Plan 9的术语说这是一个联合(union)目录,行为像成组目录的连接一样。Bind和mount的一个标志参数指定在联合目录中新目录的位置,允许在联合目录之前或之后增加新元素或用新元素整个地替换。当在联合目录中执行查找文件时,联合目录的每一部分被依次查找,首次匹配的作为结果;同样的,当读一个联合目录时,组成目录的每一部分的内容被依次读取。联合目录是Plan 9名字空间的组成性特征中最广泛使用的一个。例如,目录/bin被构造成/$cputype/bin(程序二进制文件),/rc/bin(shell脚本)以及可能由用户提供的更多的目录组成的一个联合目录。这种构造使得shell的$path变量成为多余的。

Union目录带来了一个问题:Union的哪一个元素接受新创建的文件。经过几次设计之后,我们决定采用下述方法。默认的,union中的目录不接受新创建的文件,尽管应用到一个已存在文件的creat系统调用正常地完成了。当一个目录被加到一个联合目录中时,bind和mount的一个标记允许在一个目录中有创建权限(名字空间的一个属性。当在一个联合目录中创建一个新文件时,它以创建权限被创建在union中的第一个目录中;如果创建失败,整个creat调用也失败。这个方案使得通常把一个私人目录放在公共的联合目录中的任何一个中,而仅允许在私人目录中创建文件。

根据约定,核心设备文件系统被绑定到/dev目录中,但是为了自举名字空间构造进程,必要说明一下:允许对没有现存名字空间的设备的直接访问。有设备驱动保存的树的根目录可以用语法#c访问,c是唯一的确定设备类型的字符(典型地是一个字母)。简单的设备驱动器提供包含一些文件的单级目录。作为一个例子,每一个串行端口被表示成一个数据和一个控制文件:


% bind -a '#t' /dev
% cd /dev
% ls -l eia*
--rw-rw-rw- t 0 bootes bootes 0 Feb 24 21:14 eia1
--rw-rw-rw- t 0 bootes bootes 0 Feb 24 21:14 eia1ctl
--rw-rw-rw- t 0 bootes bootes 0 Feb 24 21:14 eia2
--rw-rw-rw- t 0 bootes bootes 0 Feb 24 21:14 eia2ctl

bind程序是bind系统调用的一个封装;-a标记定位新目录在union的末尾。数据文件eia1和eia2可以通过串行线通信读写。与这些设备的控制对文件进行特殊操作不同,为eia1ctl和eia2ctl写的命令控制相应的设备;例如把文本字符串b1200写到/dev/eia1ctl把线速设置为1200波特率。和Unix的ioctl系统调用相比:在Plan 9中设备由文本的消息控制,不受字节顺序问题约束,且有清晰的读写语义。用shell脚本设置或调试设备是平常的。

普遍用9P协议把Plan 9的组成部分联在一起形成一个分布的系统。没有为每一个服务如rlogin,FTP,TFTP和X windows去发明新的协议,Plan 9用对文件对象的操作的方法实现服务,然后使用唯一的,经过良好说明的协议在计算机间交换信息。和NFS不一样,9P把文件看作是字节的序列而不是块的序列;还有不同,那就是9P是有状态的:客户执行远程调用过程建立指向远程文件服务器上的对象的指针。这些指针称为文件ID或fids。对文件的所有操作提供一个fid来识别远程文件系统中的一个对象。

9P协议定义17个消息,通过这些消息鉴别用户,在一个文件系统层次中遍历fid,拷贝fid,执行I/O,改变文件属性,以及创建和删除文件。它的完整规范在程序员手册(9man)的第五部分。下面是访问一个文件服务器上名字层次的过程。通过管道或网络连接建立和文件服务器的连接。一个最初的session消息执行客户进程和服务进程间的双方鉴别。attache消息把由客户进程建议的fid连接到服务器文件树的根。attache消息包括执行attache的用户ID号;自此以后,所有从根fid获得的fid拥有与那个用户相关的权限。多个用户可以共享连接,但每一个用户必须执行一个attache建立它/它的ID。

Walk消息在文件系统层次的单级间移动fid。clone消息得到一个已经建立的fid然后生成一个指向和原来文件相同的指针的拷贝。目的是在目录中移动一个文件时不丢失目录上的fid。Open消息把一个fid锁到层次中的一个具体的文件上,检查访问权限,以及为I/O准备fid。Read和write消息允许在文件中的任何位置进行I/O;传送的最大值已由协议定义。clunk消息说明客户进程没有为一个fid的进一步使用。Remove消息的行为和clunk相似,但是使和fid相关联的文件被删除以及服务器上任何相关的资源都被释放。

9p有两种形式:通过管道或网络连接发送的RPC消息和内核中的过程接口。因为核心设备驱动是直接可寻址的,就没有必要传送消息和它们通信;相反,每一个9p事务由一个直接的过程调用实现。对每一个fid,核心用一个称为channel的数据结构维护一个本地表示;因此由核心执行的所有对文件的操作都涉及到和fid关联的一个通道。最简单的例子是一个用户进程的文件描述符。它由通道构成的数组来索引。核心中的一张表提供和每一设备相应的9P消息一一对应的入口点。如来自用户的读调用通过那张表被转换成一个或多个过程调用,用存储在通道中的类型字符索引:procread,eiaread等等。每一个调用至少使用一个通道作为参数。一个特殊的核心驱动称为mount驱动把过程调用转换成消息,即它把本地过程调用转换成远程的。从效果上看,这个特殊驱动变成远程文件服务器上文件的本地代理。本地调用中的通道指针被转换成传送消息中相关联的fid。

Mount驱动是系统使用的唯一RPC机制。提供的文件的语义,而不是在它们上执行的操作创建了一个像cpu命令这样的具体服务。Mount 驱动解多路协议消息,这些消息在和文件服务器共享通信通道的客户进程间。对每一个发出的RPC消息,mount驱动为之分配一个用小整数(称为tag)标记的缓冲区。对RPC的回应也用它标记上,这被mount驱动用来匹配请求和回应。

名字空间的核心表示称为mount表。它保存一张通道间绑定列表。Mount表中的每一个入口包含一对通道:一个from通道和一个to通道。每次一个遍历(walk)成功地把一个通道移动到一个名字空间中新的位置时,就检查mount表是否一个“from”通道与新名字匹配;若是则克隆(clone)“to”通道代替原来的。联合目录通过把“to”通道转换到一张通道列表中实现:到联合目录的成功遍历返回一个“to”通道,它构成通道列表头,每一个都表示联合目录的组成目录。如果遍历没有在联合目录中的首目录中发现文件,则列表被接上,克隆下一个组成目录,且尝试遍历那个目录。

Plan 9中的每一个文件由一组整数唯一的识别:通道的类型(用作函数调用表的索引),服务器或其它相同类型(由驱动程序本地决定)的服务器相区别的设备号和一个来自名叫path和version的32位数字形成的一个qid。路径是创建文件时一个由设备驱动或文件服务器指定的文件号。只要文件被修改版本号就更新;像下一节描述的一样,它用作维护客户和服务器之间的高速缓存一致性。

类型和设备号是对UNIX主次设备号的模拟;qid是对i号的模拟。设备和类型把通道连接到一个设备驱动而qid则识别设备中的文件。如果从遍历中恢复的文件有相同的类型设备和作为安装表中入口点的qid路径,则它们是相同的文件,进行安装表中相应的替换。名字空间就是这样实现的。

文件高速缓冲

在客户端9P协议没有清楚的对高速缓冲文件的支持。文件服务器的大内存扮演它的所有客户的一个共享高速缓冲,它降低了网络上所有机器需要的内存总量。不过在客户端高速缓冲文件有合理的原因,诸如一个到文件服务器的低速连接。

Qid的版本域在每次文件被修改时都变化,它使得弱的高速缓冲一致性形式成为可能。最重要的是客户缓冲文本和可执行文件的数据段。当一个进程执行(execs)一个程序时,文件被重新打开,把qid的版本和高速缓冲中的相比较;若匹配,则使用本地备份。可以使用相同的方法构建一个本地缓冲文件系统。这个用户级服务器把9P连接插入到远程服务器,监视本地磁盘的流量和拷贝的数量。当它看到一个队已知数据的读时,它直接回答,而写被立即传送,使高速缓冲被写穿(write-through)保持了中央拷贝为最新。这对终端上的进程是透明的且不要求改变9P;它在串行线连接的家用机上工作的很好。相似的方法可用来在未用的本地存储器上构件一个通用的客户高速缓冲,但是在Plan 9中没这样做。

网络及通信设备

网络接口是驻留在核心的文件系统,是对较早描述的EIA设备的模拟。通过向和设备相关的控制文件写入文本字符串实现调用设置和关闭;通过读写数据文件来收发信息。设备的结构和语义对所有的网络是公共的,而不是一个文件名替换,同一过程创建一个跨以太网的使用TCP的调用,像URP对Datakit一样[Fra80]。
这样的例子演示了TCP设备的结构:


% ls -lp /net/tcp
d-r-xr-xr-x I 0 bootes bootes 0 Feb 23 20:20 0
d-r-xr-xr-x I 0 bootes bootes 0 Feb 23 20:20 1
--rw-rw-rw- I 0 bootes bootes 0 Feb 23 20:20 clone
% ls -lp /net/tcp/0
--rw-rw---- I 0 rob bootes 0 Feb 23 20:20 ctl
--rw-rw---- I 0 rob bootes 0 Feb 23 20:20 data
--rw-rw---- I 0 rob bootes 0 Feb 23 20:20 listen
--r--r--r-- I 0 bootes bootes 0 Feb 23 20:20 local
--r--r--r-- I 0 bootes bootes 0 Feb 23 20:20 remote
--r--r--r-- I 0 bootes bootes 0 Feb 23 20:20 status
%

顶级目录/net/tcp包含一个clone文件和一个用于每一个连接的目录,号数从0到n。每一个连接目录对应于一个TCP/IP连接。打开clone保留一个未用的连接,且返回它的控制文件。读这个控制文件就返回文本形式的连接号,因此用户进程可以创建新分配的连接目录的完整名字。Local,remote和status文件是诊断;例如remote包含远端的地址(对于TCP,是IP地址和端口号)。

通过写一个connect消息初始化一个调用,此消息带有一个作为参数的具体的网络地址;例如,为打开一个和远程机器的Telnet会话(端口号23)用IP地址135.104.9.52,字符串是:
connect 135.104.9.52!23
向控制文件写块(block)直到建立了连接;如果目标不可到达,则写返回一个错误。一旦建立连接,telnet应用程序读写数据文件以和远端的Telnet守护程序对话。在另一端,Telnet守护程序启动,通过写:
announce 23
到它的控制文件说明它希望接受对此端口的调用。在Plan 9中这样的守护程序被称为listener。

网络设备的一个统一结构不能隐藏不同网络的寻址和通信细节。例如,Datakit使用文本的层次式的地址(和IP的32位地址不同),因此给出一个控制文件的应用程序必须还要知道它表示的网络。不是让每个应用程序都知道每个网络的寻址,Plan 9把这些细节称为CS的连接服务器中。CS是一个安装在已知位置的文件系统,它提供一个控制文件,应用程序用它发现如何连接到主机。应用程序为想要创建的连接写符号的地址和服务名,读回要打开的克隆文件的名字和表示它的地址。如果在机器间有多个网络,CS就表示出一张可能网络和地址的列表,以逐个尝试;它使用启发式方法确定顺序。例如,它表示成最高带宽优先的。

一个称为dial的库函数和CS对话以建立连接。使用dial的应用程序不需要改变,甚至不需要重新编译就能适应新的网络;CS的接口隐藏了细节。

在Plan 9中网络的统一结构使得import是所有建构网关所需要的。

网络的核心结构

用来构建Plan 9通信通道的内核探查被称为streams[Rit84][presotto]。流是一个双向通道。它把一个物理的设备或伪设备连接到一个用户进程。用户进程在流的一段插入和删除数据,内核进程根据设备在另一端操作。一个流由一个进程模块的线性列表组成。每一模块有一个向上流(朝向进程)和向下流(朝向设备)的put过程。在流的任一端调用put过程就把数据插入到流中。每一个模块调用后继的一个以向上或向下发送数据。像Unix的流一样[Rit84],Plan 9的流可以被动态的配置。

IL协议

9P协议必须运行在带定界消息的可靠传输协议上。9P没有从传输错误中恢复的机制,系统假定每一次对通信通道的读会返回一个9P消息;它不会为了发现消息边界而分析数据流。管道和一些网络协议已经有这些属性,但标准的IP协议没有。TCP不划定消息边界,而UDP[RFC768]不提供可靠的顺序吞吐。

我们设计了一个新协议称为IL(Internet Link),通过IP传输9P消息。它是一个基于连接的协议,提供机器之间可靠的顺序消息传送。因为每一进程只有一个未决的9P请求,因此IL不需要流控制。像TCP一样,IL有自适应超时设定:它测定(scale)确认与重传时间以匹配网络速度。这让协议能很好地在Internet和本地以太网上运行。同样IL不会盲目重传,是为了避免给繁忙的网络增加拥挤。完整的细节在另一篇文章中[Prwi95]。在Plan 9中IL的实现比TCP更小更快,IL是我们主要的Internet传输协议。

鉴别概述

鉴别为访问资源的用户建立一个ID。请求资源的用户称为客户(client),授予对资源的访问的用户称为服务器(server)。这通常在一个9P消息attach的帮助下完成。服务器总是依据某些用户,一个普通客户或某些管理实体而活动,因此,鉴别被定义为用户间的,而不是机器间的。

每一个Plan 9用户由一个相关的DES[NBS77]鉴别密钥(key);对用户ID的审查是通过加密和解密特殊消息的能力实现的,此消息称为询问(challenge),因为对一个用户的密钥的知晓才让用户访问它的资源,Plan 9的鉴别协议从来不传送一个有清楚可读(cleartext)的密钥的消息。

鉴别是双向的:在鉴别交换(exchange)结束时,每一方都确信了另一方的身份。每一机器用内存中的一个DES密钥开始交换。在CPU和文件服务器的一方,密钥、用户名、和服务器的域名是从永久存储中得到的,通常是非易失性的RAM。在终端一方,密钥是在引导时从用户输入的口令获得。一个特殊的机器,即鉴别服务器,为它的管理域中所有的用户和鉴别协议中的参与者维护一个密钥数据库。

鉴别协议如下:交换询问(challenge)之后,一方和鉴别服务器联系以创建权限保证(permission-granting)的票据(ticket);这个票据用每一方的保密密钥加密且包含一个新的会话密钥。每一方解密自己的票据,且用会话密钥加密另一方的询问。

这个结构有点像Kerberos[MBSS87],但是避免了它对同步时钟的信任。和Kerberos不一样的还有,Plan 9鉴别支持一个“speak for”关系[LABW91];它能使一个用户拥有另一个用户的授权;CPU服务器就是这样根据它的客户的行为而运行进程的。

Plan 9的鉴别结构构建安全的服务而不是依赖于防火墙。鉴于防火墙对每一种服务渗透的“墙”都要求特殊的代码,Plan 9方法允许鉴别在一个地方-9P(对所有服务)完成。例如,命令安全地运行在Internet上。

鉴别外部连接

正规的Plan 9鉴别协议不适合于像Telnet或FTP这样的基于文本的服务。这种情况下,Plan 9用户用手头上的称为鉴别码(authenticator)的DES算子鉴别。鉴别码为用户处理一个密钥,它不同于用户的普通鉴别密钥。用户使用一个4位数字的PIN登录到鉴别码。正确的PIN使得一个询问/回应的鉴别码和服务器交换。因为一个询问/回应交换只有一次是合法的,且密钥从不通过网络传送,这个过程不受中继攻击(relay attacks)的影响,还和Telnet及FTP这样的协议兼容。

特殊用户

Plan 9没有超级用户。每一服务器负责维护自己的安全,通常只允许从控制台访问,它由一个口令保护。例如,文件服务器有唯一的一个管理的用户称为adm,它的特殊特权是仅能应用到由服务器的物理控制台输入的命令。这些特权考虑到服务器每天的维护,如添加新用户和配置磁盘及网络。特权不包含修改,检查或改变文件权限的能力。如果一个文件被某用户只读保护,只有那个用户可以个其它人授予访问。

CPU服务器有一个相似的用户名,它允许对服务器上资源的管理性访问,这些资源如用户进程的控制文件。这样的权限是必要的,例如杀死破坏进程,但是不超出服务器的范围。另一方面,通过存储在受保护的非易失RAM中的密钥,管理的用户身份被鉴别服务器证实。这就允许CPU服务器鉴别远程用户,处于访问服务器本身以及服务器根据它们的行为而作为一个代理。

最后,一个特殊用户名为none,它没有口令且总允许连接;任何用户都可以申称自己为none。None 有受限的权限,例如,不允许检查转储文件且只能读大家都可读的文件。

隐藏在none后面的思想是对FTP服务中匿名用户的模拟。在Plan 9上,访问FTP服务器更被限制在一个特殊约束的名字空间。它把访问服务器的用户从系统程序上断开,例如/bin的内容,但使得可以创建本地文件,用户可以通过把它们显式地绑定到none而获得本地文件。受限的名字空间比通常的导出一个ad hoc目录树更安全;其结果就是围绕不被信任(untrusted)用户周围的环(cage)。

CPU命令和代理的鉴别

当为一个用户如Peter创建一个对CPU服务器的调用时,其意思是Peter用它自己的权限运行进程。为实现这个特征,CPU服务器收到调用时按以下过程处理。首先,听者(listener)进程创建一个进程处理调用。进程改变为用户none,以避免权限泄漏。它然后执行鉴别,如果是折衷的,协议核实调用的用户确实是Peter,还要向Peter证明机器是可信任的。最后,它使用鉴别协议重新添加(reattach)到所有相关的文件服务器核实它本身是Peter。这种情况下,cpu服务器是文件服务器的一个客户,依据Peter的行为执行鉴别交换的客户部分。只有CPU服务器的管理用户名字允许要求得到“speak for”Peter时,鉴别服务器才会给进程票据以完成鉴别。

“Speak for”关系被保存在鉴别服务器上的一张表中。为了简化对在不同鉴别域中计算的用户的管理,它还包含不同域中用户名间的照映,例如,就像一个域中的用户rtm和另一个域中的rtmorris是同一个人。

文件权限

构造如文件系统这样的服务的一个优势是自然地得出了解决所有权和权限问题的方法。和在Unix中一样,每一个文件或目录对文件的所有者,文件的组及其它任何人都有独立的读写,执行/搜索权限。组的想法是不一般的:任何用户名都潜在地是一个组名称。组就是带有组中其它用户列表的一个用户。习惯在成了不同,大多数用户由用户名却没有组成员,而组有附属的名字的长列表。例如,传统上sys组有所有的系统程序员,系统文件可以用组sys访问。考虑以下的存储在服务器上的一个用户的两行信息:


pjw:pjw:
sys::pjw,ken,philw,presotto

第一行把用户pjw建立为一个正规用户。第二行建立一个名为sys的组,列出了组中的四个成员用户。空的帽号分隔的域是命名为组领袖的用户的空间。如果组有一个领袖,则那个用户有组的特殊权限,如可以自由改变组中文件的组权限。若没有指定领袖,则组中每一个成员被平等对待,就像每一个都是领袖一样。在我们的例子中,只有用户pjw可以向它的组中添加成员,但是sys中的所有成员都是这个组中平等的伙伴。

正规文件由创建它们的用户所有。组名称从持有新文件的目录继承。设备文件被特别处理:内核可能把一个文件的所有权和权限安排给访问此文件的适当用户。

提供的一般性的好例子是进程文件,它被进程的所有者所有及读保护。若所有者想让另外的某人访问进程的存储区,例如让程序的作者调试一个破坏的图像,则对进程文件应用标准命令chmod完成此时。

文件权限的另一个不寻常应用是转储文件系统,它不仅由和原始数据一样的文件服务器提供,而且用相同的用户数据表示。因此转储的文件就给予和正规文件系统中的文件一样的保护;如果一个文件由pjw所有和读保护,只要它在转储文件系统它就仍然由pjw所有和读保护。而且,因为转储文件系统是不变的,其文件不能被改变;它被永远的读保护。不利的一点是如果文件是可读的,但应当已经是读保护的,则它就是永远可读的,且那个用户名难于重新使用。

性能

作为对Plan 9核心的一个简单测量,我们比较了在两种系统上完成相同的简单操作需要的时间:Plan 9系统和SGI的IRIX Release 5.3,它运行在SGI Challenge M机器上,它有一个100MHz MIPS R4400处理器和一个1MB二级高速缓冲。测试程序用Alef写成,用相同的编译程序编译,且运行在相同的硬件上,所以只有操作系统和库是不同的。

程序测试了以下操作的时间:一个上下文切换(Plan 9上的rendezvous,IRIX上的blockproc();一个平凡的系统调用(rfork(0)和nap(0));以及轻量级fork(rfork(RFPROC()和sproc(PR_SFDS|PR_SADDR))。它还测试了从一个进程通过管道向另一个进程发送一个字节的时间和两进程间一个管道的吞吐量。结果如下表:




尽管所花的时间并不特别有优势,但是还是说明核心和商业系统是有竞争力的。

讨论

Plan 9由一个常规的核心;系统的新奇之处是核心之外的部分和它们之间相互作用的方式。在构建Plan 9时,我们综合考虑了系统的所有方面,用最合适的方法解决问题。有时方法产生了许多组成部分。一个例子就是异构指令体系结构的问题,通过编译器(不同的编码字符,可移植的目标码),环境($cputype和$objtype),名字空间(绑定在/bin中)以及其它部分来寻址。有时许多问题可以在一个地方解决。最好的例子是9P,它集中了命名,访问和鉴别。9P实际上是系统的核心部分;可以清楚地说Plan 9核心主要地就是一个9P多路转换器。

Plan 9集中于文件和命令是它的表现性的中心。尤其在分布式计算中,命名事物的方式对系统[Nee89]有深远的影响。局部名字空间的结合以及对互连网络的资源的全局约定避免了维护一个全局同一名字空间的困难,而把所有的东西都像文件命名使得系统易于理解,即使对于新手也是这样。考虑转储文件系统,任何人都可以像层次文件系统一样简单的使用它。在更深的层次上,把所有资源构造在一个统一的接口上使得易于互操作。一旦一个资源导出一个9P接口,它可以透明地和系统的任何其它部分结合以构建不一般的应用;其细节被隐藏了。这听起来好像是面向对象的,但是和它有所区别。第一,9P定义一个固定的“方法”集合;它不是一个可扩展协议。更为重要的是,文件被良好的定义以及易于理解,且用和访问,保护,命名及网络相类似的方法预打包。尽管对象有共性,但是对象没有这些已经定义的属性。通过把“对象”还原为“文件”,Plan 9获得了一些出于自由的技术(technology for free)。

不仅如此,还可能把基于文件计算的思想推向更远。把系统中的每一个资源转换为文件系统是一种比喻,且比喻会被滥用。关于限制的一个好例子是/proc,它仅仅是进程的一个视图,而不是进程的表示。要运行进程,通常的fork和exec调用仍然是必须的,而不是像这样做:


cp /bin/date /proc/clone/mem

这个例子的问题是要求服务器做不在其控制之下的事情。像这样为一个命令指定方法的能力并不意味着这个方法并不自然地得出对9P请求生成的回答的结构。作为一个相关的例子,Plan 9不把机器的网络名字放到文件名空间。网络接口提供一个非常不同的命令模型,因为对这样的文件使用open,create,read和write不提供一个合适的地方来放置所有的为任意网络建立的调用细节,这不意味着网络接口不能提供类文件的,仅仅是因为必须要有一个更紧凑定义的结构。

下一步我们会做哪些不同的呢?实现的某些部分不令人满意。在核心中使用流来实现网络接口允许协议可以被一起被动态的连接,诸如添加同一个TTY驱动到TCP,URP和IL连接,但是Plan 9没有使用这个配置能力。(已经做了努力,然而,在research Unix 系统中为实现此目的发明了流技术。)使用静态的I/O队列替换流不仅使代码简化且加快代码的运行。

尽管主要的Plan 9核心可以移植到许多机器上,但文件服务器被独立地实现。这已经导致了几个问题:驱动程序必须写两次,同样必须两次排除错误,且降低了文件系统代码的可移植性。方法时容易的:文件服务器核心应作为一个正规操作系统的变形来维护,它没有用户进程,且没有特殊的为了实现文件服务的内编译(compiled-in)核心进程。对文件系统的另一个改进会是内部结构的变化。WORM光盘柜是硬件中最不可靠的部分,但是因为它保存文件系统的元数据(metadata),为了提供文件它必须是在场的(present)。系统可以用适当驻留在磁盘上的文件系统重构,因此WORM只是一个备份设备了。这不会要求改变内部接口。

尽管Plan 9有每个进程的名字空间,它还没有这样的机制:把一个进程名字空间的描述给除了直接继承的进程以外的进程。例如CPU命令一般不能再现终端的名字空间;它只能重新解释用户的登录概貌(profile)文件,为诸如要装入的二进制目录名创建一个替代者。这就丢失了在运行CPU命令之前所做的任何本地修改。相反,捕获终端名字空间且把它的描述传送给一个远程进程应当是可能的。

虽然有些问题,Plan 9还是工作的很好。它已经成为一个支持我们的研究的成熟系统,而不是对研究本身的约束。新的试验性工作包括开发更快的网络接口,客户核心中的文件高速缓冲,封装和导出名字空间,以及在一个服务器崩溃后重新建立客户状态的能力。现在的注意力集中于用这个系统构造分布是应用。

Plan 9成功的一个原因是我们用它完成我们日常的工作,而不仅仅作为一个研究工具。当出现活跃的用户时,它们促使我们查找缺陷,以使系统适应于解决我们的问题。经过这一过程,Plan 9已经变成一个舒服而有生产效率的程序设计环境,而且是进一步系统研究的手段。