一、總結
在寫之前,先唠幾句,《UNIX環境高級編程》,簡稱APUE,這本書簡直是本神書,像我這種小白,基本上每看完一章都是“哇”這種很吃驚的表情。其實大概三年前,那會大三,我就買了這本書,也看過一些,但好像沒有留下什麼印象,今天再看,依然覺得像新的一樣。很大的原因我想是一直以來都在用Windows(用windows做開發為什麼學不到真正的技術,我想大家都懂的),當然知識結構不完整,學習能力這些就不說了。所以,對於那些致力於想在Linux下做開發的人來說,這本說一定是強推的。
UNIX環境高級編程中文第二版PDF高清版 下載地址 http://www.linuxidc.net/thread-2063-1-1.html
如果你分得清write和發fwrite,read和fread這些函數的區別,那這章也許就對你沒什麼吸引力了。本人之前面試騰訊,也被問到這個問題,當時胡亂瞎扯了一通,也真是囧。
這章大體上講了兩件事:1)什麼是不帶緩沖的I/O;2)如何在多個進程間共享文件。作為總結,我用自己的話簡單說一下這兩個問題,詳細的內容可以看上面這幅圖。
對於第一個問題,不帶緩沖指的是每個read和write這些文件I/O操作都調用的是系統調用,屬於內核態的操作。而諸如fread和fwrite這些標准I/O操作屬於用戶態操作,具體是庫函數的實現,需要借助用戶緩沖區來實現(關於用戶態和內核態的理解請看Linux探秘之用戶態與內核態)。所以,不帶緩沖是相對帶用戶緩沖區來說的(如果只從字面上理解緩沖,其實文件I/O也是帶緩沖的,只不過內核緩沖區,具體後面開一篇博客來講)
對於第二個問題,文件的共享需要讓多個文件間扯上關系,不然也沒轍。UNIX使用三種數據結構(進程表項,文件表項和V-Node節點表項)來表示一個打開的文件,如下圖。這樣當多個進程訪問一個文件,只用新建一個進程表項,然後引用對應的文件即可。其中存在著:一個進程對應一個獨立的文件表項,一個文件僅有一個V-Node表項。
因為一個文件僅有一個V-Node表項,所以,為了保證文件在多個進程間共享,需要謹慎處理好文件的一致性。比如兩個進程A和B要寫數據到一個文件,一般調用的是lseek和write這兩個函數,首先A lseek寫入的位置(如1500),然後轉到B 也lseek到1500,又轉到A開始write 100個字節,文件長度變為1600個字節,又轉到B,但B此時從第1500個字節處開始write,這就造成寫文件錯誤。因此,對於這樣的多個操作造成文件共享信息的不一致,UNIX給出的解決方案是原子操作,對於上面這種情況的一個解決方案是使用open+O_APPEND組合的原子操作。
二、看圖說話
一圖勝過千言,看圖!
Unix環境高級編程 源代碼地址 http://www.linuxidc.com/Linux/2011-04/34826.htm
Unix環境高級編程源碼編譯 http://www.linuxidc.com/Linux/2011-09/42503.htm
apue.h頭文件(Unix環境高級編程) http://www.linuxidc.com/Linux/2012-01/51729.htm
《Unix環境高級編程》(第二版)apue.h的錯誤 http://www.linuxidc.com/Linux/2011-04/34662.htm
Unix環境高級編程第二版讀書筆記 http://www.linuxidc.com/Linux/2011-04/34235.htm
《Unix環境高級編程》中apue.h的問題 http://www.linuxidc.com/Linux/2013-01/77686.htm