linux c 11 运行库,11.1.3 运行库与I/O
11.1.3? 運行庫與I/O
在了解了glibc和MSVC的入口函數的基本思路之后,讓我們來深入了解各個初始化部分的具體實現。但在具體了解初始化之前,我們要先了解一個重要的概念:I/O。
IO(或I/O)的全稱是Input/Output,即輸入和輸出。對于計算機來說,I/O代表了計算機與外界的交互,交互的對象可以是人或其他設備(如圖11-3所示)。
圖11-3? 計算機的I/O設備
而對于程序來說,I/O涵蓋的范圍還要寬廣一些。一個程序的I/O指代了程序與外界的交互,包括文件、管道、網絡、命令行、信號等。更廣義地講,I/O指代任何操作系統理解為"文件"的事務。許多操作系統,包括Linux和Windows,都將各種具有輸入和輸出概念的實體--包括設備、磁盤文件、命令行等--統稱為文件,因此這里所說的文件是一個廣義的概念。
對于一個任意類型的文件,操作系統會提供一組操作函數,這包括打開文件、讀文件、寫文件、移動文件指針等,相信有編程經驗的讀者對此都不會陌生。有過C編程經驗的讀者應該知道,C語言文件操作是通過一個FILE結構的指針來進行的。fopen函數返回一個FILE結構的指針,而其他的函數如fwrite使用這個指針操作文件。使用文件的最簡單代碼如下:
#include int main(int argc,char** argv)
{
FILE* f = fopen( "test.dat", "wb" );
if( f == NULL )
Return -1;
fwrite( "123", 3, 1, f );
fclose(f);
在操作系統層面上,文件操作也有類似于FILE的一個概念,在Linux里,這叫做文件描述符(File Descriptor),而在Windows里,叫做句柄(Handle)(以下在沒有歧義的時候統稱為句柄)。用戶通過某個函數打開文件以獲得句柄,此后用戶操縱文件皆通過該句柄進行。
設計這么一個句柄的原因在于句柄可以防止用戶隨意讀寫操作系統內核的文件對象。無論是Linux還是Windows,文件句柄總是和內核的文件對象相關聯的,但如何關聯細節用戶并不可見。內核可以通過句柄來計算出內核里文件對象的地址,但此能力并不對用戶開放。
下面舉一個實際的例子,在Linux中,值為0、1、2的fd分別代表標準輸入、標準輸出和標準錯誤輸出。在程序中打開文件得到的fd從3開始增長。fd具體是什么呢?在內核中,每一個進程都有一個私有的"打開文件表",這個表是一個指針數組,每一個元素都指向一個內核的打開文件對象。而fd,就是這個表的下標。當用戶打開一個文件時,內核會在內部生成一個打開文件對象,并在這個表里找到一個空項,讓這一項指向生成的打開文件對象,并返回這一項的下標作為fd。由于這個表處于內核,并且用戶無法訪問到,因此用戶即使擁有fd,也無法得到打開文件對象的地址,只能夠通過系統提供的函數來操作。
在C語言里,操縱文件的渠道則是FILE結構,不難想象,C語言中的FILE結構必定和fd有一對一的關系,每個FILE結構都會記錄自己***對應的fd。
FILE、fd、打開文件表和打開文件對象的關系如圖11-4所示。
圖11-4? FILE結構、fd和內核對象
圖11-4中,內核指針p指向該進程的打開文件表,所以只要有fd,就可以用fd+p來得到打開文件表的某一項地址。stdin、stdout、stderr均是FILE結構的指針。
對于Windows中的句柄,與Linux中的fd大同小異,不過Windows的句柄并不是打開文件表的下標,而是其下標經過某種線性變換之后的結果。
在大致了解了I/O為何物之后,我們就能知道I/O初始化的職責是什么了。首先I/O初始化函數需要在用戶空間中建立stdin、stdout、stderr及其對應的FILE結構,使得程序進入main之后可以直接使用printf、scanf等函數。
【責任編輯:云霞 TEL:(010)68476606】
點贊 0
總結
以上是生活随笔為你收集整理的linux c 11 运行库,11.1.3 运行库与I/O的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下编译openjdk7,Ubu
- 下一篇: linux windows 丢失,Win