轉載請注明來源:https://www.cnblogs.com/hookjc/
在文已經共享的情況下如何操作,也就是當多個進程同時操作同一個文件時,我們怎么保證文件數據的正確性。linux通常采用的方法是文件上鎖,來避免共享資源的產生競爭狀態。
文件鎖包括建議性鎖和強制性的鎖。建議性的,顧名思義,相對溫柔一些,在對文件進行鎖操作時,會檢測是否已經有鎖存在,並且尊重已有的鎖。在一般的情況下,內核和系統都不使用建議鎖。強制性的鎖是由內核執行的鎖,當一個文件被上鎖進行寫入操作的時候,內核將阻止其他進程對其進行讀寫操作。采取強制性的鎖對性能的影響很大,每次進行讀寫操作都必須檢查是否有鎖存在。
在linux中對文件進行鎖操作,可以使用lockf()和fcntl()這兩個函數,前者對文件施加建議性鎖,后者為兩種鎖都行。另外fcntl還可以對文件的某一記錄上鎖。
fcntl使用格式為:
int fcntl(int fd,int cmd,struct flock *lock);
fd為文件描述符,cmd為一些命令參數,flcok結構體用來設置記錄鎖的具體狀態。
fcntl() 對已打開的文件描述符進行操作,並根據命令參數的不同能夠執行不同的任務。關於文件鎖的幾個命令選項如下:
-
F_GETLK 根據lock參數值,決定是否上文件鎖
F_SETLK 設置lock參數值的文件鎖
F_SETLKW 這是 F_GETLK的阻塞版本,在無法獲取鎖時,會進入睡眠狀態。
flock結構體的定義如下:
struct flock {
short l_type;
off_t l_start;
short l_whence;
off_t l_len;
pid_t l_pid;
}
l_type有三個選項:
F_RDLCK : 共享鎖,只讀用
F_WRLCK : 獨占鎖(寫操作鎖)
F_UNLCK : 解除鎖定
l_start 為相對位移量
l_whence 必須是以下幾個值之一( 在 unistd.h 中定義):
SEEK_SET : 文件開始位置
SEEK_CUR: 文件當前位置
SEEK_END: 文件末尾位置
l_len 加鎖的長度
l_pid當前文件操作的進程id號
下面是簡單的例子
運行結果:
讀是可以共享的。
寫的例子:
運行結果:
同時寫的話,發生競爭,后者不能對文件做寫操作,只有當當前的鎖解開,后續的才可寫文件