posix是什么都不知道,就別說你懂Linux了!
一、什么是posix?
1. 概念
POSIX:可移植操作系統(tǒng)接口(Portable Operating System Interface of UNIX,縮寫為 POSIX ),2. 發(fā)布者-IEEE
發(fā)布者為電氣與電子工程師協(xié)會(Institute of Electrical and Electronics Engineers),簡稱IEEE。這個協(xié)會老牛了【該組織在太空、計算機、電信、生物醫(yī)學、電力及消費性電子產(chǎn)品等領域中都是主要的權威】!POSIX是IEEE為要在各種UNIX操作系統(tǒng)上運行的軟件而定義的一系列API標準的總稱,其正式稱呼為IEEE 1003,而國際標準名稱為ISO/IEC 9945。POSIX.1 已經(jīng)被國際標準化組織(International Standards Organization,ISO)所接受,被命名為 ISO/IEC 9945-1:1990 標準。IEEE,總部位于美國紐約,是一個國際性的電子技術與信息科學工程師的協(xié)會,也是目前全球最大的非營利性專業(yè)技術學會。IEEE致力于電氣、電子、計算機工程和與科學有關的領域的開發(fā)和研究,在太空、計算機、電信、生物醫(yī)學、電力及消費性電子產(chǎn)品等領域已制定了1300多個行業(yè)標準,現(xiàn)已發(fā)展成為具有較大影響力的國際學術組織
3. POSIX標準下載
主頁:http://blog.csdn.net/ablo_zhou很多人聽說了POSIX標準,但標準具體長什么樣,在哪里下載到,則 不清楚。現(xiàn)在我開放出來,供相關人員使用。Single UNIX Specification V3,IEEE Std 1003.1,2004 Edition標準線上地址:http://www.unix.org/version3/online.html 注冊后可以在線閱讀或者下載。IEEE和Open Group 的POSIX認證:http://www.opengroup.org/certification/idx/posix.html相關頁面:http://www.unix.org/version3/ieee_std.html二、POSIX歷史
1. 起源
POSIX是Unix的標準。1974年,貝爾實驗室正式對外發(fā)布Unix。因為涉及到反壟斷等各種原因,加上早期的Unix不夠完善,于是貝爾實驗室以慷慨的條件向?qū)W校提供源代碼,所以Unix在大專院校里獲得了很多支持并得以持續(xù)發(fā)展。于是出現(xiàn)了好些獨立開發(fā)的與Unix基本兼容但又不完全兼容的OS,通稱Unix-like OS。包括:- 美國加州大學伯克利分校的Unix4.xBSD(Berkeley Software Distribution)。
- 貝爾實驗室發(fā)布的自己的版本,稱為System V Unix。
- 其他廠商的版本,比如Sun Microsystems的Solaris系統(tǒng),則是從這些原始的BSD和System V版本中衍生而來。
2. 誰遵循這個標準呢?
首先就是大名鼎鼎的Unix和Linux了,除此之外還有蘋果的操作系統(tǒng)也是Unix-based的。有了這個規(guī)范,你就可以調(diào)用通用的API了,Linux提供的POSIX系統(tǒng)調(diào)用在Unix上也能執(zhí)行,因此學習Linux的底層接口最好就是理解POSIX標準。3. 支持POSIX-Linux成功的最重要一個因素
Linux之所以能夠成功,有很多因素,但是支持POSIX標準無疑是它能夠快速發(fā)展的最重要的一個因素。POSIX 標準的制定最后投票敲定階段大概是 1991~1993 年間,而此時正是Linux 剛剛起步的時候,這個 UNIX 標準為 Linux 提供了極為重要的信息,使得 Linux 能夠在標準的指導下進行開發(fā),并能夠與絕大多數(shù) UNIX 操作系統(tǒng)兼容。在最初的 Linux 內(nèi)核源碼(0.01版、0.11版)中就已經(jīng)為 Linux 系統(tǒng)與 POSIX 標準的兼容做好了準備工作。在 Linux 0.01 版內(nèi)核 /include/unistd.h 文件中就已經(jīng)定義了幾個有關 POSIX 標準要求的符號常數(shù),而且 Linus 在注釋中已寫道:“OK,這也許是個玩笑,但我正在著手研究它呢”。正是由于Linux支持POSIX標準,無數(shù)可以在unix上運行的程序都陸續(xù)的移植到Linux上,而此時unix因為版權問題,官司打的不可開交,使得Linux后來者居上。時也命也!下面是祖師爺Linus當年申請POSIX標準的郵件:來自:torvalds@klaava.Helsinki.Fi(林納斯·托瓦茲)
討論組:comp.os.minix
主題:Gcc-1.40和一個有關POSIX的問題
信息名稱:?1991?Jul?3,?100050.9886@klaava.Helsinki.Fi
日期:?1991年7月3日,?格林威治時間10:?00:?50
各位網(wǎng)友好!
由于我現(xiàn)在正在MINIX系統(tǒng)下做一個項目,?對POSIX標準很感興趣。?有誰能向我提供
一個(最好)?是機器可讀形式的最新的POSIX規(guī)則??能有FTP地址就更好了。
POSIX標準是一個可以適用于數(shù)以百計的UNIX系統(tǒng)呼叫中的任意一個的一套冗長規(guī)則,?計算機要執(zhí)行任務(從讀、?寫、?開機和關機開始)?就需要這個標準。?
POSIX則是指一個UNIX的標準體系,?或一個由來自不同公司的代表所組成的一個組織,?希望按照一個共同的標準進行運作。?對于程序員開發(fā)的在該操作系統(tǒng)下的新應用軟件或開發(fā)應用軟件的新版本而言,?標準是極其重要的。?從POSIX這樣的系統(tǒng)呼叫(system call)?,?尤其是重要的呼叫(call)?中,?我可以獲得一個操作系統(tǒng)應該具有哪些功能的一個單子;?然后我就可以通過自己的方式在自己的系統(tǒng)中實現(xiàn)每一個功能。?通過編寫出這些標準,?我的系統(tǒng)軟件的源代碼將可以被別人使用,?以開發(fā)新的應用軟件。
當時我并不知道我本可以直接從POSIX公司買到這些規(guī)則的軟盤,?但這無所謂。?哪怕我能買得起,?什么東西運到芬蘭,?往往會需要很長的時間。?我不愿等上那么久,?因此我四處搜求一個能從FTP地址上直接下載的版本。
沒有人給我提供能找到POSI標準的來源。?于是我開始了計劃B。
我從學校找到運行sun器(sun server)的sun微系統(tǒng)版的UNIX手冊。?該手冊中有一個完全可以湊合使用的系統(tǒng)呼叫的基本版本。?從用戶手冊中能看出系統(tǒng)呼叫的主要功能,?以及為完成這些功能所需要完成的步驟。?但是,?從中看不出具體的方法,?而只是標明了最終的結果。?于是我便著手從安德魯·塔南鮑姆的書中和別的材料中收集一些系統(tǒng)呼叫。?
最終有人給我寄來了那幾卷厚厚的POSIX標準。
三、可移植性
聊到POSIX,那我們就不得不說說到底什么是可移植性,在講可移植性之前,我們先來了解庫函數(shù)和系統(tǒng)調(diào)用的區(qū)別。Linux下對文件操作有兩種方式:系統(tǒng)調(diào)用(system call)和庫函數(shù)調(diào)用(Library functions)。1. 系統(tǒng)調(diào)用
系統(tǒng)調(diào)用是通向操作系統(tǒng)本身的接口,是面向底層硬件的。通過系統(tǒng)調(diào)用,可以使得用戶態(tài)運行的進程與硬件設備(如CPU、磁盤、打印機等)進行交互,是操作系統(tǒng)留給應用程序的一個接口。2. 庫函數(shù)
庫函數(shù)(Library function)是把函數(shù)放到庫里,供別人使用的一種方式。方法是把一些常用到的函數(shù)編完放到一個文件里,供不同的人進行調(diào)用。一般放在.lib文件中。庫函數(shù)調(diào)用則是面向應用開發(fā)的,庫函數(shù)可分為兩類,- 一類是C語言標準規(guī)定的庫函數(shù),
- 一類是編譯器特定的庫函數(shù)。
3. 庫函數(shù)API和系統(tǒng)調(diào)用的區(qū)別
- (1) 庫函數(shù)是語言或應用程序的一部分,而系統(tǒng)調(diào)用是內(nèi)核提供給應用程序的接口,屬于系統(tǒng)的一部分
- (2) 庫函數(shù)在用戶地址空間執(zhí)行,系統(tǒng)調(diào)用是在內(nèi)核地址空間執(zhí)行,庫函數(shù)運行時間屬于用戶時間,系統(tǒng)調(diào)用屬于系統(tǒng)時間,庫函數(shù)開銷較小,系統(tǒng)調(diào)用開銷較大
- (3) 系統(tǒng)調(diào)用依賴于平臺,庫函數(shù)并不依賴
4. 程序的可移植性及其本質(zhì)
那么目標代碼和啟動代碼是怎么生成的呢?答案是編譯器。編程語言編寫的程序首先要被編譯器編譯成目標代碼(0、1代碼),然后在目標代碼的前面插入啟動代碼,最終生成了一個完整的程序。要注意的是,程序中為訪問特定設備(如顯示器)或者操作系統(tǒng)(如windows xp ?的API)的特殊功能而專門編寫的部分通常是不能移植的。綜上所述,一個編程語言的可移植性取決于
- 不同平臺編譯器的數(shù)量
- 對特殊硬件或操作系統(tǒng)的依賴性
#ifdef?_WINDOWS_
???????CreateThread();??????//windows下線程的創(chuàng)建
#else
???????Pthread_create();????//Linux下線程的創(chuàng)建
#endif
對于頭文件,也使用同樣的預編譯宏來實現(xiàn)。如:#ifndef?_WINDOWS_
???????#include?
#else
???????#include?
#endif
這樣就可以實現(xiàn)代碼的可移植了。在編譯的時候只要通過#define就可以選擇在那個平臺下完成程序的編譯。綜上所述,我們都是將C,C 等各種語言當作中間層,以實現(xiàn)其一定程度上的可移植。如今,語言的跨平臺的程序都是以這樣的方式實現(xiàn)的。但是在不同的平臺下,仍需要重新編譯。5. 系統(tǒng)開銷
使用系統(tǒng)調(diào)用會影響系統(tǒng)的性能,在執(zhí)行調(diào)用時的從用戶態(tài)切換到內(nèi)核態(tài),再返回用戶態(tài)會有系統(tǒng)開銷。為了減少開銷,因此需要減少系統(tǒng)調(diào)用的次數(shù),并且讓每次系統(tǒng)調(diào)用盡可能的完成多的任務。硬件也會限制對底層系統(tǒng)調(diào)用一次所能寫的數(shù)據(jù)塊的大小。為了給設備和文件提供更高層的接口,Linux系統(tǒng)提供了一系列的標準函數(shù)庫。使用標準庫函數(shù),可以高效的寫任意長度的數(shù)據(jù)塊,庫函數(shù)在數(shù)據(jù)滿足數(shù)據(jù)塊長度要求時安排執(zhí)行底層系統(tǒng)調(diào)用。一般地,操作系統(tǒng)為了考慮實現(xiàn)的難度和管理的方便,它只提供一少部分的系統(tǒng)調(diào)用,這些系統(tǒng)調(diào)用一般都是由C和匯編混合編寫實現(xiàn)的,其接口用C來定義,而具體的實現(xiàn)則是匯編,這樣的好處就是執(zhí)行效率高,而且,極大的方便了上層調(diào)用。隨著系統(tǒng)提供的這些庫函數(shù)把系統(tǒng)調(diào)用進行封裝或者組合,可以實現(xiàn)更多的功能,這樣的庫函數(shù)能夠?qū)崿F(xiàn)一些對內(nèi)核來說比較復雜的操作。比如,read()函數(shù)根據(jù)參數(shù),直接就能讀文件,而背后隱藏的比如文件在硬盤的哪個磁道,哪個扇區(qū),加載到內(nèi)存的哪個位置等等這些操作,程序員是不必關心的,這些操作里面自然也包含了系統(tǒng)調(diào)用。而對于第三方的庫,它其實和系統(tǒng)庫一樣,只是它直接利用系統(tǒng)調(diào)用的可能性要小一些,而是利用系統(tǒng)提供的API接口來實現(xiàn)功能(API的接口是開放的)。四、舉例
如下圖是Linux系統(tǒng)調(diào)用的大概流程。當應用程序調(diào)用printf()函數(shù)時,printf函數(shù)會調(diào)用C庫中的printf,繼而調(diào)用C庫中的write,C庫最后調(diào)用內(nèi)核的write()。而另一些則不會使用系統(tǒng)調(diào)用,比如strlen, strcat, memcpy等。printf函數(shù)執(zhí)行過程中,程序運行狀態(tài)切換如下:用戶態(tài)–>系統(tǒng)調(diào)用–>內(nèi)核態(tài)–>返回用戶態(tài)
printf函數(shù)、glibc庫和系統(tǒng)調(diào)用在系統(tǒng)中關系圖如下:實例代碼如下:??1?#include?
??2?
??3?
??4?int?main(int?argc,?char?**argv)
??5?{
??6?????printf("yikoulinux");???
??7?????return?0;
??8?}???
編譯執(zhí)行ospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;">root@ubuntu:/home/peng/test#?gcc?123.c?-o?run
root@ubuntu:/home/peng/test#?strace?./run
如執(zhí)行結果可知:我們的程序雖然只有一個printf函數(shù),但是在執(zhí)行過程中,我們前后調(diào)用了execve、access、open、fstat、mmap、brk、write等系統(tǒng)調(diào)用。其中write系統(tǒng)調(diào)用會把字符串:yikoulinux通過設備文件1,發(fā)送到驅(qū)動,該設備節(jié)點對應終端stdout。【注意】運行程序前加上strace,可以追蹤到函數(shù)庫調(diào)用過程
版權申明:內(nèi)容來源網(wǎng)絡,版權歸原創(chuàng)者所有。除非無法確認,都會標明作者及出處,如有侵權煩請告知,我們會立即刪除并致歉。謝謝!