APUE - File I/O (3) - File Sharing
Posted on 2007-08-20 22:39 ZelluX 閱讀(641) 評論(0) 編輯 收藏 所屬分類: Linux 、C/C++內核使用三種數據結構表示一個打開的文件,他們之間的關系決定了進程間對于共享文件的作用。
Every process has an entry in the process table. Within each process table entry is a table of open file descriptors, which we can think of as a vector, with one entry per descriptor. Associated with each file descriptor are
1) The file descriptor flags (close-on-exec; refer to Figure 3.6 and Section 3.14)
2) A pointer to a file table entry
The kernel maintains a file table for all open files. Each file table entry contains
1) The file status flags for the file, such as read, write, append, sync, and nonblocking
2) The current file offset
3) A pointer to the v-node table entry for the file
Each open file (or device) has a v-node structure that contains information about the type of file and pointers to functions that operate on the file. For most files, the v-node also contains the i-node for the file. This information is read from disk when the file is opened, so that all the pertinent information about the file is readily available. For example, the i-node contains the owner of the file, the size of the file, pointers to where the actual data blocks for the file are located on disk, and so on.

上圖為這三種數據結構及其相互聯系
其中v-node主要用于提供單個操作系統上的多文件系統支持,Sun把它稱為Virtual File System
linux中沒有v-node,使用了一個generic i-node代替,盡管使用了不同的實現方式,v-node在概念上與generic i-node相同。
下面來討論兩個獨立的進程打開同一文件的情況
這種情況下兩個進程擁有不同的file table,但其中的兩個指針指向了同一個v-node。
知道了這些數據結構的情況以后,我們可以更精確的知道某些操作的結果
1) 每次write操作結束后,當前文件的offset增加,如果這個操作導致當前的offset超出了文件長度,則i-node表中記錄的文件大小會被修改為改動后的大小。
2) 使用O_APPEND方式打開文件后,每次調用write函數時,當前文件的offset都會被設置為i-node表中的該文件大小,從而write函數只能在文件尾部追加。
3) lseek 函數只改變在file table中的當前文件offset,并不會產生io操作
注意file descriptor flag和file status flag的作用域差別,前者屬于某個單獨進程的單獨的file descriptor,后者則適用于任意進程中指向給定file table entry的所有descriptor。fcntl函數可以修改這兩種flag
Every process has an entry in the process table. Within each process table entry is a table of open file descriptors, which we can think of as a vector, with one entry per descriptor. Associated with each file descriptor are
1) The file descriptor flags (close-on-exec; refer to Figure 3.6 and Section 3.14)
2) A pointer to a file table entry
The kernel maintains a file table for all open files. Each file table entry contains
1) The file status flags for the file, such as read, write, append, sync, and nonblocking
2) The current file offset
3) A pointer to the v-node table entry for the file
Each open file (or device) has a v-node structure that contains information about the type of file and pointers to functions that operate on the file. For most files, the v-node also contains the i-node for the file. This information is read from disk when the file is opened, so that all the pertinent information about the file is readily available. For example, the i-node contains the owner of the file, the size of the file, pointers to where the actual data blocks for the file are located on disk, and so on.

上圖為這三種數據結構及其相互聯系
其中v-node主要用于提供單個操作系統上的多文件系統支持,Sun把它稱為Virtual File System
linux中沒有v-node,使用了一個generic i-node代替,盡管使用了不同的實現方式,v-node在概念上與generic i-node相同。
下面來討論兩個獨立的進程打開同一文件的情況
這種情況下兩個進程擁有不同的file table,但其中的兩個指針指向了同一個v-node。
知道了這些數據結構的情況以后,我們可以更精確的知道某些操作的結果
1) 每次write操作結束后,當前文件的offset增加,如果這個操作導致當前的offset超出了文件長度,則i-node表中記錄的文件大小會被修改為改動后的大小。
2) 使用O_APPEND方式打開文件后,每次調用write函數時,當前文件的offset都會被設置為i-node表中的該文件大小,從而write函數只能在文件尾部追加。
3) lseek 函數只改變在file table中的當前文件offset,并不會產生io操作
注意file descriptor flag和file status flag的作用域差別,前者屬于某個單獨進程的單獨的file descriptor,后者則適用于任意進程中指向給定file table entry的所有descriptor。fcntl函數可以修改這兩種flag