鎖 記錄上鎖

2021-10-10 19:45:26 字數 2753 閱讀 9834

記錄鎖的功能是:當乙個程序正在讀或者修改檔案的某乙個部分時,它可以阻止其他程序修改同一檔案區。記錄鎖其實是

位元組範圍鎖,因為它鎖定的只是檔案中的乙個區域,也可能是整個檔案。

1.基礎介紹

svr3通過fcntl函式增加了記錄鎖功能。fcntl函式的原型已經在以前給出,這邊再重複一次。

#include

intfcntl

(int filedes,

int cmd,..

./* struct flock *flockptr */);

對於記錄鎖,cmd是f_getlk、f_setlk或f_setlkw。第三個引數是乙個指向flock結構的指標。

struct flock

;

關於加鎖解鎖區域注意以下幾點:

1.l_start是相對偏移量,l_whence決定了相對偏移量的起點。這與lseek函式中最後兩個引數類似。

2.該區域可以在當前檔案尾端處開始或越過其尾端處開始,但是不能在檔案起始位置之前開始。

3.如若l_len為0,則表示鎖的區域從其起點(由l_start和l_whence決定)開始直至最大可能偏移量為止。(也就是不管新增到該檔案中多少資料,它們都處於鎖的範圍內)

4.為了鎖整個檔案,我們設定l_start和l_whence,使鎖的起點在檔案起始處,並且說明l_en為0.

上面說到的讀寫鎖和執行緒互斥中的讀寫鎖原理差不多:

以下說明fcntl函式的三種命令:

f_getlk:判斷由flockptr所描述的鎖是否會被另外一把鎖所排斥。如果存在一把鎖,它阻止建立由flockptr所描述的鎖,

則把該現存鎖的資訊寫到flockptr指向的結構中,如果不存在這中情況,則除了將l_type設定為unlck之外,flockptr所指向

結構的其他資訊保持不變。

f_setlk:設定由flockptr所描述的鎖,如果試圖建立一把鎖(讀鎖或者寫鎖),而按上述相容性規則不能允許,則fcntl立即

出錯返回,此時errno設定為eacces或eagain。此命令也用來消除由flockptr說明的鎖(l_type為unlock)

f_setlkw:這是f_setlk的阻塞版本,如果因為當前在所請求區間的某個部分另乙個程序已經有一把鎖,因而按相容性

規則由flockptr所請求的鎖不能被建立,則使呼叫程序休眠,如果請求建立的鎖已經可用或者休眠由訊號終端,則該程序被喚醒。

在設定或釋放檔案上的鎖時,系統按照要求組合或裂開相鄰區,例如,若位元組100~199是加鎖區,需解鎖第150位元組,則核心

將維持兩把鎖,一把用於位元組100149,另一把用於位元組151199.

這裡寫描述

假定我們又對第150位元組設定鎖,那麼系統將會把三個相鄰的加鎖區合併成乙個區,其結果如上圖的第一圖所示。

2.函式呼叫

2.1請求和釋放一把鎖

為了避免每次分配flock結構,然後又填入各項資訊,可以用lock_reg來處理所有這些細節:

int

lock_reg

(int fd,

int cmd,

int type, off_t offset,

int whence, off_t len)

用以下巨集來呼叫:

#define read_lock(fd, offset, whence, len) \

lock_reg((fd), f_setlk, f_rdlck, (offset), (whence), (len))

#define readw_lock(fd, offset, whence, len) \

lock_reg((fd), f_setlkw, f_rdlck, (offset), (whence), (len))

#define write_lock(fd, offset, whence, len) \

lock_reg((fd), f_setlk, f_wrlck, (offset), (whence), (len))

#define writew_lock(fd, offset, whence, len) \

lock_reg((fd), f_setlkw, f_wrlck, (offset), (whence), (len))

#define un_lock(fd, offset, whence, len) \

lock_reg((fd), f_setlk, f_unlck, (offset), (whence), (len))

2.2測試一把鎖

pid_t lock_test

(int fd,

int type, off_t offset,

int whence, off_t len)

如果存在一把鎖,則函式返回持有該鎖的程序的程序id,否則返回0。

通常用下面的巨集來呼叫函式:

#define is_read_lockable(fd, offset, whence, len) \

(lock_test((fd), f_rdlck, (offset), (whence), (len)) == 0)

#define is_write_lockable(fd, offset, whence, len) \

(lock_test((fd), f_wrlck, (offset), (whence), (len)) == 0)

注意:程序不能使用lock_test函式測試它自己是否在檔案的某一部分持有一把鎖。

linux IPC 記錄上鎖

本節講述的是利用fcntl函式來實現不同程序間的上鎖,不管這些程序有沒有親緣關係。前面講述過有名訊號量同樣也是可以用在沒有親緣關係的程序間上鎖的。而針對執行緒上鎖的一些機制,想要用在不同程序間上鎖,就需要把鎖放在程序共享記憶體區操作。記錄上鎖主要是用到fcntl 函式。include include...

UNIX網路程式設計 記錄上鎖

記錄鎖是讀寫鎖的一種擴充套件型別,可用於親緣關係或無親緣關係的程序之間共享某個檔案的讀與寫。被鎖住的檔案通過檔案描述符進行訪問,執行上鎖的操作函式是fcntl,這種型別的鎖通常在核心中維護。記錄鎖的功能是 乙個程序正在讀或修改檔案的某個部分時,可以阻止其他程序修改同一檔案區,即其鎖定的是檔案的乙個區...

UNIX網路程式設計卷二 筆記 讀寫鎖和記錄上鎖

讀寫鎖用於讀取資料比修改資料更頻繁的場景,它的分配規則如下 1.沒有執行緒持有寫鎖時,任意多的執行緒可以持有讀鎖。2.僅當沒有執行緒持有讀鎖或寫鎖時,才能分配寫鎖。當已有執行緒持有讀鎖時,另一線程申請寫鎖則會阻塞,若後續還有讀鎖的申請,此時有兩種策略 1.對後續的讀鎖請求都通過,可能會造成因讀鎖不斷...