內核使用三種數據結構表示打開的文件,它們之間的關係決定了在文件共享方面一個進程對另外一個進程可能產生的影響。數據結構
1>每一個進程在進程表中都有一個記錄項,記錄項中包含有一張打開文件描述符表,可將其視爲一個矢量,每一個描述項佔用一項。與每一個文件描述符相關聯的是:函數
注:其中close-on-exec標誌,若是某個文件符設置了該標誌,fcntl(fd, F_SETFD, 1), 則在該進程調用exec函數以前爲exec族函數關閉對應的文件描述符。spa
2>內核爲全部打開文件維持一張文件表項。每一個文件表項包含:指針
注:在文件表或者v索引節點中都有索引計數,引用計數爲0的時候,文件引用爲0的時候就能夠收回此表項blog
fork後父子進程各自的每個打開的文件描述符共享同一個文件表項索引
3>每一個打開文件(或設備)都有個v節點結構。v節點包含了文件類型和對此文件進行各類操做的函數指針。 對於大多數文件,v節點還包含了該文件的i節點(索引節點)。這些信息是在打開文件時從磁盤上讀入內存的,因此全部關於文件的信息都是快速可供使用的。進程
例如:i節點包含了文件的全部者、文件長度、文件所在設備、只想文件實際數據塊在磁盤上所在位置的指針等等。內存
注:Linux沒有使用v節點,而是使用了通用的i節點結構。雖然這兩種實現有所不一樣,但在概念上,v節點和i節點是同樣的。二者都指向文件系統所特有的i節點結構。同步
兩個獨立進程各自打開同一個文件(下圖),此圖中能夠看出,對於同一個文件,打開該文件的每一個進程都獲得一個文件表項,但對一個給定的文件只有一個v節點表項。而每一個進程都有本身的文件表項的一個理由是:使每一個進程都有它本身的對該文件的當前偏移量。it
dup後的文件表項
原子操做:
由踱步組成的一個操做,若是該操做原子地執行,要麼執行完全部的步驟,要麼一步也不執行,不可能只執行全部步驟的一個子集。