???? 在linux中,打開的文件組織結構如下:
與打開的文件相關的有三個數據結構,就是上圖中的三部分。
UNIX環境高級編程。???? 在linux中,有一個進程表,每一個進程在進程表中有一個表項。每一個進程表項中都維護著一張打開文件的描述符表,每一個文件描述符占用了一個表項。只要文件被打開,就都會在這張表中存在一個文件描述符,而不管該描述符是否是該進程打開的。與文件描述符相關聯的是文件描述符標志和文件表項指針。文件表項指針指向文件表項,什么是文件表項呢?內核為每一個打開的文件都維護了一個文件表項。這個文件表項記錄了以下信息:文件打開的狀態(只讀,只寫或者可讀可寫),當前文件的偏移量(用來記錄文件的下次要讀或者寫文件的位置)以及文件的v節點指針。內核為每一個打開的文件還維護了一個v節點,這個節點包括了文件的類型以及各種操作文件的指針。另外它還包括i節點,i節點包括文件的所有者以及文件的長度等信息,這些信息是在打開文件時從磁盤上讀進來的,因此可以看到在程序中獲取打開文件的相關信息是十分快速的。
???? 每次向一個文件中寫入數據后,文件表項的文件位移會增加相應的字節數。當文件的位移超過i節點中當前文件的長度時,當前文件的長度會設置為當前文件的位移。如果文件以O_APPEND的方式打開時,每次向文件中寫入數據前,都會將當前文件指針設置為i節點中的當前文件長度。
???? 如果有兩個進程打開了同一文件,則內核為這兩個進程分別維護一個文件表項,這樣做的理由是兩個進程可以有獨立的文件位移,這種情況,圖示如下:
雖然內核為每一個進程都維護了一個文件表項,但是內核對每一個文件只維護了一個v節點。在這種情況下,多個進程同時對一個文件進行讀操作是完全沒有問題的,但是如果多個進程同時對一個文件進行寫操作,就有可能造成最終的文件并不是我們所想要的結果。這個問題就引出了原子操作的概念。
UNIX/LINUX????? 原子操作是由一系列操作構成的一個集合,這個集合中的操作,要么全部執行,要么全不執行,絕不可能只執行了這個指令集合的一個真子集。考慮這樣一個進程,它每次將數據添加到文件的末尾,在早期的linux中沒有O_APPEND操作,所以程序會寫成如下的形式:
if( lseek(fd,0L,SEEK_END)<0 )
{printf("lseek error!\n");return -1;
} if( write(fd,buff,100)!=100 )
{printf("write file error!\n");return -2;
}
???? dup函數和dup2函數用來復制一個文件描述符,它們的函數原型是:
int dup(int filedes);
int dup2(int filedes,int filedes2);
如果函數執行成功,則返回新的文件描述符,否則返回-1。dup函數的參數是所要復制的文件描述符,返回系統中尚未使用的最小的文件描述符。dup2的作用是將第一個參數指定的文件描述符復制到第二個參數制定的文件描述符上,如果第二個參數已經使用,則先將其關閉。由dup函數復制后得到的文件描述符與原文件描述符指向同一個文件表項,如下圖:
unix網絡編程 pdf、???? fcntl函數用來改變打開文件的性質,它的函數原型是:
int fcntl(int filedes,int cmd,...);
如果函數執行成功返回值依賴于cmd,如果函數執行失敗則返回-1。cmd的取值有以下幾種情況:
F_DUPFD:復制文件描述符,相當于dup和dup2的功能
F_GETFD / F_SETFD:獲取/設置文件描述符標志
F_GETFL / F_SETFD:獲取/設置文件狀態標志
F_GETOWN / FSETOWN:獲取設置異步IO所有權
F_GETTLK / F_SETTLK / F_SETTLKW:獲得設置記錄鎖
其中,最常使用的是前面三個選項。
unix網絡高級編程????? ioctl函數是io操作的雜物箱,可以進行各種亂七八糟的io操作。
???? 系統中存在/dev/fd/n,這個目錄,n的值為0,1,2等,打開文件/dev/fd/n等于復制文件描述符n。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态