標籤: linux
io程式設計
fcntl
2013-05-30 13:52
2422人閱讀收藏
舉報
linux應用程式設計(52)
作者同類文章x
檔案鎖
上一節:講述的5個基本函式函式open()、read()、write()、lseek()和close()實現的檔案的開啟、讀/寫等操作,本節將討論在檔案已經共享的情況下如何操作,也就是當多個使用者共同使用、操作乙個檔案的情況。這時,linux通常採用的方法是給檔案上鎖,來避免共享的資源產生競爭的狀態。
檔案鎖包括建議性鎖和強制性鎖。建議性鎖要求每個上鎖檔案的程序檢查是否有鎖存在,並且尊重已有的鎖。在一般情況下,核心和系統都不使用建議性鎖。強制性鎖是由核心執行的鎖,當乙個檔案被上鎖執行寫入操作時,核心將阻止其他任何檔案對其進行讀寫操作。採用強制性鎖對效能影響很大,每次讀寫都必須檢查是否有鎖存在。
在linux中,實行檔案上鎖的函式有lockf()和fcntl(),其中lockf()用於對檔案施加建議性鎖,而fcntl()不僅可以施加建議性鎖,還可以施加強制性鎖。同時,fcntl()還能對檔案的某一記錄上鎖,也就是記錄鎖。
記錄鎖又可分為讀取鎖和寫入鎖,其中讀取鎖又稱為共享鎖,它能夠使多個程序都能在檔案的同一部分建立讀取鎖。而寫入鎖又稱為排斥鎖,在任何時刻只能有乙個程序在某個部分建立寫入鎖。當然,在檔案的同一部分不能同時建立讀取鎖和寫入鎖。
fcntl()函式具有很豐富的功能,它可以對已開啟的檔案描述符進行各種操作,不僅包括管理檔案鎖,還包括獲得設定檔案描述符和檔案描述符標誌、檔案描述符的複製等很多功能!這一次我先學習一下fcntl()函式建立檔案鎖的方法,關於它的另外的用法...先學會了這個再說吧!
fcntl()函式格式
表1中的lock是乙個flock結構體,結構如下:
上圖中的 off_t 就是資料型別 long int ;pid_t 就是資料型別 int,不懂這裡有解釋:點此解釋
那麼這個結構體lock中每個變數的取值含義如下表2
基礎實驗
本實驗主要是為了練習一下fcntl()函式的檔案記錄鎖的功能。下面首先給出了使用fcntl(0函式的檔案記錄鎖功能的**實現。
在該**中,首先給flock結構體的對應位賦予相應的值。接著呼叫兩次fcntl()函式,使用f_getlk命令判斷是否可以進行flock結構體所描述的鎖操作:若可以進行,則flock結構的l_type會被設定為f_unlck,其他域不變;若不可進行,則l_pid被設定為擁有檔案鎖的程序號,其他域不變。
用f_setlk和f_setlkw命令設定flock結構所描述的鎖操作,後者是前者的阻塞版。
當第一次呼叫fcntl()時,使用f_fetlk命令獲得當前檔案被上鎖的情況,由此可以判斷能不能進行上鎖操作;當第二次呼叫fcntl()時,使用f_setlkw命令對指定檔案進行上鎖/解鎖操作。因為f_setlkw命令是阻塞式操作,所以,當不能把上鎖/解鎖操作進行下去時,執行會被阻塞,直到能夠進行操作為止。
檔案記錄鎖的功能**具體如下:
/*lock_set.c*/下面的**是檔案寫入鎖的測試用例,這裡首先建立乙個hello.c檔案,然後對其上鎖,最後釋放寫入鎖。**如下所示:int lock_set(int fd,int type)
else if(lock.l_type==f_wrlck) /*該檔案已經有寫入鎖 */
}/*l_type 可能在執行完上述判斷後被修改了*/
lock.l_type=type;
/*根據不同的type值進行阻塞式上鎖或解鎖*/
if((fcntl(fd,f_setlkw,&lock))<0)
switch(lock.l_type)
break;
case f_wrlck:
break;
case f_unlck:
break;
default:break;
} /*end of switch*/
return 0;
}
/*write_lock.c*/檔案結構如下圖:#include
#include
#include
#include
#include
#include
#include"lock_set.c"
int main(void)
/*給檔案上寫入鎖*/
lock_set(fd,f_wrlck);
getchar(); /*當使用者輸入任意鍵後,程式繼續執行,否則等待*/
/*給檔案解鎖*/
lock_set(fd,f_unlck);
getchar();
close(fd); /*關閉該檔案*/
exit(0);
}
使用命令:gcc write_lock.c -o write_lock編譯
為了使程式有較大的靈活性,我們的程式中採用檔案上鎖後由使用者輸入任意鍵使程式繼續執行。為了更好地顯示寫入鎖的作用,在這裡我們開兩個終端,並且在終端上同時執行該程式,以達到多個程序操作乙個檔案的效果。首先執行終端1,請注意終端2中的第一句話
由上圖可見,寫入鎖為互斥鎖,同一時刻只能有乙個寫入鎖存在。
接下來測試檔案讀取鎖,原理和上邊一樣,**如下
/*read_lock.c*/在兩個終端下執行的結果如下圖:#include
#include
#include
#include
#include
#include
#include"lock_set.c"
int main(void)
/*給檔案上讀取鎖*/
lock_set(fd,f_rdlck);
getchar(); /*當使用者輸入任意鍵後,程式繼續執行,否則等待*/
/*給檔案解鎖*/
lock_set(fd,f_unlck);
getchar(); /*當使用者輸入任意鍵後,程式繼續執行,否則等待*/
close(fd); /*關閉該檔案,釋放鎖*/
exit(0);
與寫入鎖的執行結果比較,可有看出,讀取鎖為共享鎖,當程序7170已設定讀取鎖後,程序7294仍然可以設定讀取鎖。
總結:這一節講了檔案鎖的問題,那麼咱們再來想一下:為什麼要有檔案鎖?原因就是當檔案共享,也就是多個使用者共同使用、操作乙個檔案的情況,為了避免共享的資源產生競爭的狀態,linux就採用了給檔案上鎖的方法。
頂 2
踩 0
我的同類文章
linux應用程式設計(52)
Linux系統程式設計8 檔案I O
fcntl.h 標頭檔案,file control的縮寫。open函式,openat函式 int open const char path,int oflag int openat int fd,const char path,int oflag 將準備開啟的檔案或是裝置的名字作為引數path傳給函...
檔案IO程式設計二
上一章主要是講了檔案系統以及整個操作的流程,這一講主要是講vfs虛擬檔案系統 引言 linux中允許眾多不同的檔案系統共存,如ext2,ext3,vfat等。通過使用同一套檔案i o系統呼叫即可對linux中的任意檔案進行操作而無需考慮檔案系統格式。對檔案的操作也可以跨檔案系統而執行。我們可以使用c...
Linux系統程式設計 檔案IO 一
最近在在實驗樓上學linux,做點筆記。上面的課程對於學習linux還不錯,有興趣可以看看。檔案io linux提供給了使用者程式一些介面,用來呼叫執行相關的功能。大多數linux檔案i o只需要用到5個函式 open,read,write,lseek和close 檔案描述符 檔案描述符是乙個非負整...