本节书摘来自异步社区《linux系统编程(第2版)》一书中的第1章,第1.3节,作者:【美】robert love著,更多章节内容可以访问云栖社区“异步社区”公众号查看
unix系统编程是门古老的艺术。unix编程的基础理念在几十年来一直根深蒂固。但是,对于unix系统,变化却是无处不在。各种行为不断变化,特性不断增加。为了使unix世界变得有序,标准化组织为系统接口定义了很多套官方标准。虽然存在很多这样的官方标准,但是linux没有遵循任何一个标准。相反地,linux致力于和两大主流标准兼容:posix和单一unix规范(single unix specification,sus)。
除了其他内容,posix和sus为类unix操作系统定义了一套c api。该c api为兼容的unix系统定义了系统编程接口,至少从中抽取出了通用的api集。
1.3.1 posix和sus的历史
在20世纪80年代中期,电气电子工程师协会(ieee)开启了unix系统上的系统级接口的标准化工作。自由软件运动(free software movement)的创始人richard stallman建议把该标准命名成posix(发音[pahz-icks]),其全称是portable operating system interface(可移植操作系统接口)。
该工作的第一成果是在1988年获得通过的ieee std 1003.1-1988(简称posix 1988)。1990年,ieee对 posix标准进行了修订,通过了ieee std 1003.1-1990(posix 1990)。后续的修订ieee std 1003.1b-1993(posix 1993或称posix.1b)和ieee std 1003.1c-1995(posix 1995或称posix.1c)分别描述了非强制性的实时和线程支持。2001年,这些非强制性标准在posix 1990的基础上进行整合,形成单一标准ieee std 1003.1-2001(posix 2001)。最新的标准ieee std 1003.1-2008 (posix 2008)在2008年12月发布。所有的核心posix标准都简称为posix.1,其中2008年的版本为最新版。
从20世纪80年代后期到20世纪90年代初期,unix系统厂商卷入了一场“unix之战”中,每家厂商都处心积虑地想将自己的unix变体定义成真正的“unix”操作系统。几大主要的unix厂商聚集在了工业联盟the open group周围,the open group是由开放软件基金会(open software foundation,osf)和x/open合并组成。the open group提供证书、白皮书和兼容测试。在20世纪90年代初,正值unix之战如火如荼,the open group发布了单一unix规范(sus)。sus广受欢迎,很大原因归于sus是免费的,而posix标准成本很高。今天,sus合并了最新的posix标准。
第一个版本的sus发布于1994年,然后在1997年和2002年分别发布了两个修订版susv2和susv3。最新的susv4在2008年发布。susv4修订结合了ieee std 1003.1-2008标准以及一些其他标准。本书将以posix标准介绍系统调用和其他接口,原因是sus是对posix的扩展。
1.3.2 c语言标准
dennis ritchie和brian kernighan的经典著作《c程序设计语言》(prentice hall)自1978年首次出版后,一直扮演着非正式的c语言规范的角色。这个版本的c语言俗称k&r c。c语言很快替代了basic语言和其他语言,成为微型计算机编程的通用语言。因此,为了对当时已经非常流行的c语言进行标准化,美国国家标准协会(ansi)成立了委员会制定c语言的官方版本。该版本集成了各个厂商的特性和改进,并借鉴了新兴的c++语言的一些经验。这个标准化过程漫长而又艰辛,但是ansi c在1989年最终顺利完成。1990年,国际标准化组织(iso)基于ansi c做了一些有效修改,批准了iso c90。
1995年,iso发布了新版的c语言标准iso c95,虽然该标准很少被执行。在1999年,对c语言做了很多修订,形成了iso c99标准,它引入了很多新的特征,包括inline函数、新的数据类型、变长数组、c++风格的注释以及新的库函数。该标准的最新版本是iso c11,该版本最重要的功能是格式化的内存模型,支持跨平台的线程可移植性。
对于c++,iso标准化进展却非常缓慢。经过几年的发展以及非向前兼容的编译器的发布,通过了第一代c++标准iso c98。虽然该标准极大地提高了编译器之间的兼容性,但在某些方面限制了一致性和可移植性。2003年通过了iso c++03标准。它修复了编译器开发人员遇到的一些bug,但是没有用户可见的变化。下一个是目前最新的iso标准c++11(之前的版本都是c++0x,c++11意味着该版本发布更令人期待),有更多的语言和标准的库附加组件及改进——由于修改非常多,很多人建议c++11作为一门不同的语言,和之前的c++版本区别开。
1.3.3 linux和标准
正如前面所述,linux旨在达到兼容posix和sus。susv4和posix 2008描述了linux提供的接口,包括支持实时(posix.1b)和线程(posix.1c)。更重要的是,linux努力与posix与sus需求兼容。一般来说,如果和标准不一致,就认为是个bug。人们认为linux与posix.1和susv3兼容,但是由于没有经过posix或sus的官方认证(尤其是linux的每次修订),所以无法官方宣布linux兼容posix或sus。
关于语言标准,linux很幸运。gcc c编译器兼容iso c99,而且正在努力支持c11。g++ c++编译器兼容iso c++03,正在努力支持c++11。此外,gcc和g++_实现了c语言和c++语言的扩展。这些扩展统称为gnu c,在附录a中有相关描述。
linux的前向兼容做得不是很好[1],虽然近期这方面已经好多了。接口是通过标准说明的,如标准的c库,总是可以保持源码兼容。不同版本之间的二进制代码兼容是由glibc来保证的。由于c语言是标准化的,gcc总是能够准确编译合法的c程序,尽管gcc相关的扩展可能会废弃掉甚至从新的gcc发布版本中删除。最重要的是,linux内核保证了系统调用的稳定性。一旦系统调用是在linux内核的稳定版本上实现的,它就不会改变了。
在各种linux发布版中,linux标准规范(linux standard base,lsb)对大部分的linux系统进行了标准化。lsb是几大linux厂商在linux基金会(前身是自由标准组织)推动下的联合项目。lsb扩展了posix和sus,添加了一些自己的标准;它尝试提供二进制标准,支持目标代码在兼容系统上无需修改即可运行。大多数linux厂商都在一定程度上遵循了lsb标准。
1.3.4 本书和标准
本书有意避免对任何标准的介绍“夸夸其谈”。大多数情况下,unix系统编程相关的书籍都不应该浪费篇幅探讨以下内容:如某个接口在不同标准下行为有何不同,特定的系统调用在各个系统上的实现情况,以及类似的口舌之战。本书仅涉及在现代linux系统上的系统编程,它是通过最新版本的linux内核(3.9)、gcc编译器(4.8)和c库(2.17)来实现的。
因为系统接口通常是固定不变的(linux内核开发人员尽力避免破坏系统调用接口),并且支持一定程度的源码和二进制兼容性。因此,我们可以深入探索linux系统接口的细节,不必关心与各种其他的unix系统和标准的兼容性问题。专注于探讨linux也使得本书能够深入探讨linux最前沿的,并且在未来很长时间依然举足轻重的接口。本书阐述了linux的相关知识,一些组件如gcc和内核的实现和行为,从专业角度洞察linux的最佳实践和优化技巧。