標籤:io ar os 使用 sp on 檔案 資料 問題
在上一篇章中我們主要學習了一個獨立的程式是如何在系統上啟動並執行,可是我們在實際編寫程式的時候,會發現程式有時還要與IO裝置或者別的程式互動和通訊。這一篇章主要來學習程式與IO裝置互動的知識。
程式與IO裝置的互動是經常可以見到的,比如與磁碟、鍵盤、網路的互動。UNIX系統設計中一切皆檔案的思想,因此所有的IO裝置都被模型化為檔案。這種思想使得我們在讀寫檔案的時候可以忽略檔案的底層機制,只用read、write函數即可對所有不同類型的檔案來進行讀取。在UNIX系統級要想讀寫檔案中的內容,那麼open、close、read、write這四個函數大家肯定要知道了。
首先我先來介紹一下我們經常在讀檔案時碰到的EOF,核心對每個開啟的檔案都保持著一個檔案位置。對於read函數,讀檔案就是從檔案拷貝n個位元組到儲存空間,如果當前的檔案位置到檔案的結尾不足n個位元組時,返回實際讀到的位元組數,如果再次讀的話,會觸發一個稱為end-of-file的條件,應用程式可以檢測到這個條件。在檔案的結尾處並沒有EOF符號。
其次我們來介紹一下共用檔案。大家對於如下這個程式不知有何看法?假設hh.txt中的值為abc。
#include <stdio.h>
#include <sys/type.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd1, int fd2;
char c;
fd1 = open("hh.txt", O_RDONLY, 0);
fd2 = open("hh.txt", O_RDONLY, 0);
read(fd1, &c, 1);
read(fd2, &c, 1);
printf("%c", c);
close(fd1);
close(fd2);
return 0;
}
那我來告訴大家結果,列印出來的值為a。在核心中用三種資料結構來表示開啟的檔案。第一種是int型的描述符,即上面程式中的fd1、fd2。每個進程都有一張描述符表。第二種是開啟檔案表,所有進程共用,它裡面主要儲存著檔案的位置,以及開啟檔案的檔案位置即讀檔案時如果讀了一個字元,那麼這個檔案位置就不再是0而是1了。第三種是v-node表,所有進程共用。主要儲存著檔案的屬性。
對於上面的程式,開啟檔案表就有兩個,每個檔案表中都儲存著開啟檔案的位置,他們是相互獨立的,因此在最後一次read的時候,讀的還是a。
當然我們在寫程式時大部分的時候是不使用這幾個系統級函數的,已經有人為我們開發出了一套標準io函數以供我們使用,比如printf,fopen,fread。
對於我們程式與別的程式的通訊與互動(典型的例子就是用戶端與伺服器)主要是使用通訊端來完成的,通訊端是對網路抽象的一種檔案類型,它也是用檔案描述符來引用的,這樣我們前面講解的東西對通訊端也完全適用。
對於多線程編程的情況,即不同線程間程式與程式的互動與通訊。這裡要考慮的問題還是比較多的,並且模型也與前面的模型不太一樣,為了不影響這篇文章的主題,這裡就不再累贅了,下次有空的時候為大家講解。
你真的深入理解電腦系統了嗎之篇章二------程式與程式的互動