天天看點

《Linux系統程式設計(第2版)》——1.3 标準

本節書摘來自異步社群《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的最佳實踐和優化技巧。