什麼是控制代碼和檔案描述符

2021-10-05 02:10:47 字數 2668 閱讀 5017

控制代碼就是乙個識別符號,只要獲得物件的控制代碼,我們就可以對物件進行任意的操作。

控制代碼不是指標,作業系統用控制代碼可以找到一塊記憶體,這個控制代碼可能是識別符號,map的key,也可能是指標,看作業系統怎麼處理的了。fd算是在某種程度上替代控制代碼吧;linux 有相應機制,但沒有統一的控制代碼型別,各種型別的系統資源由各自的型別來標識,由各自的介面操作。

在作業系統層面上,檔案操作也有類似於file的乙個概念,在linux裡,這叫做檔案描述符fd(file descriptor),而在windows裡,叫做控制代碼(handle)(以下在沒有歧義的時候統稱為控制代碼)。使用者通過某個函式開啟檔案以獲得控制代碼,此後使用者操縱檔案皆通過該控制代碼進行。

粗暴的解釋

windowns中是handle,liunx類似的是fd,最早的windows開發書籍,handle是被翻譯成「把手」的。雖然不好聽,但是個人認為相當傳神。

雖然你握住的只是把手,卻能拉動整扇門,而且你根本不用在意那門長什麼樣子

一扇門如果有多個把手,被不同的人(程序)握住,門往哪兒走就不好說了

設計這麼乙個控制代碼的原因在於控制代碼可以防止使用者隨意讀寫操作系統核心的檔案物件。無論是linux還是windows,檔案控制代碼總是和核心的檔案物件相關聯的,但如何關聯細節使用者並不可見。核心可以通過控制代碼來計算出核心裡檔案物件的位址,但此能力並不對使用者開放。

在linux系統設計裡面遵循一切都是檔案的原則,即磁碟檔案、目錄、網路套接字、磁碟、管道等,所有這些都是檔案,在我們進行開啟的時候會返回乙個fd,即是檔案控制代碼。

linux控制代碼fd不用了,都要close()。如果頻繁的開啟檔案,或者開啟網路套接字而忘記釋放就會有控制代碼洩露的現象。在linux系統中對程序可以呼叫的檔案控制代碼數進行了限制,在預設情況下每個程序可以呼叫的最大控制代碼數是1024個,如果超過了這個限制,程序將無法獲取新的控制代碼,而從導致不能開啟新的檔案或者網路套接字,對於線上伺服器即會出現服務被拒絕的情況。

下面舉乙個實際的例子,在linux中,值為0、1、2的fd分別代表標準輸入、標準輸出和標準錯誤輸出。在程式中開啟檔案得到的fd從3開始增長。fd

具體是什麼呢?在核心中,每乙個程序都有乙個私有的「開啟檔案表」,這個表是乙個指標陣列,每乙個元素都指向乙個核心的開啟檔案物件。而fd,就是這個表的下標。當使用者開啟乙個檔案時,核心會在內部生成乙個開啟檔案物件,並在這個表裡找到乙個空項,讓這一項指向生成的開啟檔案物件,並返回這一項的下標作為fd。由於這個表處於核心,並且使用者無法訪問到,因此使用者即使擁有fd,也無法得到開啟檔案物件的位址,只能夠通過系統提供的函式來操作。

在程式設計中,控制代碼是一種特殊的智慧型指標。當乙個應用程式要引用其他系統(如資料庫、作業系統 )所管理的記憶體塊或物件時,就要使用控制代碼。

在上世紀80年代的作業系統(如mac os 和windows )的記憶體管理 中,控制代碼被廣泛應用。unix 系統的檔案描述符 基本上也屬於控制代碼。和其它桌面環境 一樣,windows api 大量使用控制代碼來標識系統中的物件 ,並建立作業系統與使用者空間 之間的通訊渠道。例如,桌面上的乙個窗體由乙個hwnd 型別的控制代碼來標識。

如今,記憶體容量的增大和虛擬記憶體演算法使得更簡單的指標愈加受到青睞,而指向另一指標的那類控制代碼受到冷淡。儘管如此,許多作業系統仍然把指向私有物件的指標以及程序傳遞給客戶端的內部陣列下標稱為控制代碼。

下面內容參考:

上面提到每個程序都有乙個file陣列,裡面放的該程序用到的檔案描述符,程式的檔案描述符預設情況下 0 是輸入,1 是輸出,2 是錯誤。我們可以畫一幅圖:

對於一般的計算機,輸入流是鍵盤,輸出流是顯示器,錯誤流也是顯示器,所以現在這個程序和核心連了三根線。因為硬體都是由核心管理的,我們的程序需要通過「系統呼叫」讓核心程序訪問硬體資源。ps:不要忘了,linux 中一切都被抽象成檔案,裝置也是檔案,可以進行讀和寫。如果我們寫的程式需要其他資源,比如開啟乙個檔案進行讀寫,這也很簡單,進行系統呼叫,讓核心把檔案開啟,這個檔案就會被放到files的第 4 個位置,對應檔案描述符 3:

明白了這個原理,輸入重定向就很好理解了,程式想讀取資料的時候就會去files[0]讀取,所以我們只要把files[0]指向乙個檔案,那麼程式就會從這個檔案中讀取資料,而不是從鍵盤:

同理,輸出重定向就是把files[1]指向乙個檔案,那麼程式的輸出就不會寫入到顯示器,而是寫入到這個檔案中:

錯誤重定向也是一樣的,就不再贅述。

管道符其實也是異曲同工,把乙個程序的輸出流和另乙個程序的輸入流接起一條「管道」,資料就在其中傳遞,不得不說這種設計思想真的很巧妙:

控制代碼和檔案描述符

控制代碼是windows下的概念。控制代碼是windows下各種物件的識別符號,比如檔案 也許叫文件比較合適一點 資源 選單 游標 點陣圖等。檔案控制代碼和檔案描述符類似,它也是乙個非負整數,也用於定位檔案資料在記憶體中的位置。由於linux下所有東西都被看成是檔案,比如檔案 也許叫文件比較合適一點...

檔案控制代碼 檔案描述符

檔案控制代碼和檔案描述符 在我們跨平台開發的時候,經常會碰到這倆個概念 檔案描述符 本質上是乙個索引號 非負整數 系統使用者層可以根據它找到系統核心層的檔案資料。這是乙個posix標準下的概念,常見於linux系統。但windows也有檔案描述符這個概念,但不常用。檔案控制代碼 windows下的概...

檔案控制代碼 檔案描述符

由於程序級檔案描述符表的存在,不同的程序中會出現相同的檔案描述符,它們可能指向同乙個檔案,也可能指向不同的檔案。兩個不同的檔案描述符,若指向同乙個開啟檔案控制代碼 file 將共享同一檔案偏移量。因此,如果通過其中乙個檔案描述符來修改檔案偏移量,那麼從另乙個檔案描述符中也會觀察到變化,無論這兩個檔案...