linux 檔案記錄鎖

2021-08-18 00:06:45 字數 3377 閱讀 5746

1. 什麼是檔案記錄鎖?

是對檔案某個範圍的鎖定

2.檔案記錄鎖的功能?

當乙個程序正在讀或者修改檔案的某個部分的時候,它可以阻止其他程序修改同一檔案區

3. 檔案記錄鎖的函式介面?

fcntl()  此系統呼叫可以用來對已開啟的檔案描述符進行各種控制操作以改變已開啟檔案的各種屬性,根據傳入不同的操作型別命令

cmd,

fcntl

會執行不同的操作,

fcnt

根據cmd

不同,接收可變的引數。具體有以下五種型別的操作:

/* do the file control operation described by cmd on fd. 

the remaining arguments are interpreted depending on cmd. */

int fcntl (int __fd, int __cmd, ...);

//根據cmd的不同有以下三種型別的呼叫

int fcntl(int fd, int cmd);

int fcntl(int fd, int cmd, long arg);

int fcntl(int fd, int cmd, struct flock *lock);

/* 

cmd = f_dupfd,複製乙個檔案描述符;

*/

int fcntl(int fd, int cmd);

/* cmd = f_getfd,獲得檔案描述符標誌;

cmd = f_setfd,設定檔案描述符標誌;arg = 描述符標誌的值,目前只定義了乙個標誌: fd_cloexec

int fcntl(int fd, int cmd);

int fcntl(int fd, int cmd, long arg);

*/

/* cmd = f_getfl,獲得檔案狀態標誌;

cmd = f_setfl,設定檔案狀態標誌;arg = 狀態標誌的值

int fcntl(int fd, int cmd);

int fcntl(int fd, int cmd, long arg);

*/

/* cmd = f_getown,獲得當前接收sigio和sigurg訊號的程序id或程序組id

cmd = f_setown,設定接收sigio和sigurg訊號的程序id或程序組id;arg = 程序id或程序組id

int fcntl(int fd, int cmd);

int fcntl(int fd, int cmd, long arg);

*/

/* return value:

對於成功的呼叫,根據操作型別cmd不同,有以下幾種情況:

f_dupfd 返回新的檔案描述符

f_getfd 返回檔案描述符標誌

f_getfl 返回檔案狀態標誌

f_getown 程序id或程序組id

all other commands 返回0

呼叫失敗, 返回-1,並設定errno。

*/

上面四個功能都是fcntl提供的很常用的操作,關於記錄鎖的功能就是fcntl提供的第五個功能,具體使用如下:
int fcntl(int fd, int cmd, struct flock *lock);  

/* cmd = f_getlk,測試能否建立一把鎖

cmd = f_setlk,設定鎖

cmd = f_setlkw, 阻塞設定一把鎖

f_getlk-判斷由flockptr描述的鎖是否會被另外一把鎖排斥,若存在,則把現存鎖的資訊寫入到flockptr中,若不存在,則除了將l_type設定為f_unlck之外,結構中其餘資訊不變;

f_setlk-設定由flockptr描述的鎖,如果按照共享讀鎖和獨佔寫鎖規則,不允許加鎖,則立即返回錯誤碼;

-此命令也用於清除flockptr說明的鎖,l_type=f_unlck

f_setlkw-是f_setlk的阻塞版本,當不滿足加鎖規則時候,程序進入休眠,如果請求建立的鎖已經可用,則休眠由訊號中斷,程序被喚醒;

*/

需要注意的是,用f_getlk測試能否建立一把鎖,然後接著用f_setlk或f_setlkw企圖建立一把鎖,

由於這兩者不是乙個原子操作,所以不能保證兩次fcntl之間不會有另外乙個程序插入並建立一把相關的鎖,

從而使一開始的測試情況無效。所以一般不希望上鎖時阻塞,會直接通過呼叫f_setlk,並對返回結果進行

測試,以判斷是否成功建立所要求的鎖

//posix只定義fock結構中必須有以下的資料成員,具體實現可以增加  

struct flock ;

4.  共享讀鎖與獨佔寫鎖:

多個程序在給定的位元組上可以有一把共享的讀鎖,但是在乙個給定位元組上只能有乙個程序獨佔一把寫鎖;

如果在乙個給定位元組上已經有了一把或者多把讀鎖,可以繼續新增讀鎖,但是不能在該位元組上加寫鎖;如果在乙個位元組上已經有了一把獨佔寫鎖,則不能再新增任何讀/寫鎖;

注意:這個規則只適用於不同程序提出的鎖請求,如果單個程序對乙個檔案區間已經有了一把鎖,後來又企圖對同一檔案區加另一把鎖,那麼新鎖將替換舊鎖;

5. 記錄鎖的隱含繼承和釋放:

(1) 程序終止時,所建立的鎖全部被釋放;

(2) 關閉任何乙個描述符,則該程序通過該描述符可以引用的檔案上的任何一把鎖都被釋放;

(3) fork產生的子程序不繼承父程序鎖設定的鎖;

(4) 在執行了exec後,新程式可以繼續執行原來程式的鎖;如果對乙個描述符設定了close-on-exec,則exec執行時候,檔案描述符被關閉,對應鎖也被釋放;

6. 在檔案尾加鎖:

(1) 在加鎖之前最好是對檔案當前位置或者當前長度指定一把鎖,因為在lseek和加鎖呼叫之間,可能有另外乙個程序在改變該檔案的長度;

(2) 下面**第一次加鎖的時候,得到一把鎖,從檔案尾端開始,包括以後新增的任何資料,都會加鎖;解鎖的時候,檔案尾端已經變化了,所以並沒有解鎖;

7. 強制性鎖和建議性鎖:

合作程序,多個程序都用一致的方式處理記錄鎖,完成某些任務,這些程序集合就是合作程序;

建議性鎖:建議性鎖不做強制檢查鎖規則,需要程序自己獲取,檢查是否有鎖存在,對於合作程序來說,建議性鎖是可行的,但是對於某些非合作程序,他們不程序檢查,就對檔案進行改寫,就會對當前檔案造成影響;如建議性鎖可以比如成紅綠燈,只是建議性的,因為還是有人可以闖紅燈;

強制性鎖:核心對每個open,read,write系統呼叫都進行檢查,檢查訪問的檔案是否違背了鎖規則,如果違背了鎖規則,則該io呼叫被禁止;

linux鎖學習記錄

臨界區和競爭條件 所謂的臨界區,就是訪問和操作共享資料的額 段,多個執行執行緒併發訪問同乙個資源通常是不安全的。為了避免在臨界區中併發的執行,必須保證這些 原子的執行。如果兩個執行執行緒有可能處於同一臨界區中同事執行,那麼這就是程式的bug,如果情況真的發生,就稱之為競爭條件。這種情況出現的機會往往...

UNIX LINUX程式設計學習之檔案鎖 記錄鎖

鎖定中的幾個概念 檔案鎖定的是整個檔案,而記錄鎖定只鎖定檔案的某一特定部分。unix 的記錄指的是從檔案的某一相對位置開始的一段連續的位元組流,它不同於其它以強制性記錄結構阻止檔案的作業系統,因此,unix 記錄鎖更恰當的稱呼應該是範圍鎖,它是對檔案某個範圍的鎖定。檔案和記錄鎖定可分為諮詢式鎖定和強...

linux檔案鎖例子

lock.c include include include include struct flock file lock short type,short whence close fd lock2.c.同lock.c相比只是修改了下buf內容 include include include in...