fcntl函式+flock結構對檔案鎖的操作
**例子
協議鎖和強制鎖
檔案鎖的核心結構
unix提供了檔案鎖機制來防止多程序對同一檔案的併發操作導致的髒讀和資料混亂,同時也為多程序提供了同步機制。
鎖型別共享鎖(讀鎖)
共享鎖也稱為讀鎖。
如果乙個程序為某個檔案的某個區域加了一把共享鎖,那麼其他程序對該檔案的該區域可以加共享鎖不能加排他鎖。
排他鎖(寫鎖)
排他鎖也稱為寫鎖。
如果乙個程序為某個檔案的某個區域加了一把排他鎖,那麼其他程序無法對該檔案的該區域加任何鎖,包括共享鎖和排他鎖。
fcntl函式+flock結構對檔案鎖的操作
fcntl()
函式定義的標頭檔案:#include
函式定義:
int
fcntl
(int fd, f_getlk|f_setlk|f_setlkw,
struct flock* lock)
;
第乙個引數是需要加鎖的檔案描述符;第二個引數是fcntl函式的命令,f_getlk
、f_setlk
、f_setlkw
這三個巨集定義被用來獲取、釋放和測試鎖記錄是否存在;第三個引數為乙個指向flock結構的指標。
f_getlk
:獲取鎖記錄
f_setlk
:非阻塞模式加鎖
f_setlkw
:阻塞模式加鎖
flock
結構如下:
struct flock
;
單個程序只能持有檔案區域上的一種型別的鎖;如果將乙個新鎖設定到乙個已經被鎖定的區域,那麼舊鎖將被轉換為新的鎖型別;如果新鎖定的區域與舊鎖定的區域範圍不一致,那麼會涉及到拆分、縮小或合併現有的鎖。**例子
該程式演示了給檔案加鎖並寫入資料,資料寫入速度為每個字元一秒。如果將鎖操作的**去掉,並同時在兩個終端執行該程式,會發現檔案中的內容是混亂的。如果加上鎖就會發現寫入的資料是有序的。
#include
#include
#include
#include
#include
//加寫鎖
intwlock
(int fd,
int wait)
//加讀鎖
intrlock
(int fd,
int wait)
//解鎖
intulock
(int fd)
intmain
(void
)//加鎖if(
wlock
(fd,1)
==-1)
char
*buf =
"hello world!\n"
;for
(int i =
0; i <
strlen
(buf)
;++i)
sleep(1
);}//釋放鎖if(
ulock
(fd)==-
1)close
(fd)
;return0;
}
協議鎖和強制鎖
協議鎖:顧名思義,按照協議進行加鎖操作。如同交通規則,紅燈停綠燈行。但是你不遵守交通規則,硬闖紅燈,也能通過馬路,但是你可能會出車禍。協議鎖就如何交通規則,對檔案寫的操作,不加寫鎖可以不?可以!就算別的程序已經給該檔案加了鎖,正在寫入,你一樣的可以寫,但是你寫入的資料無法保障它的完整性,同時也破壞了別人寫入的資料完整性,讀鎖亦是如此。unix實現的就是協議鎖,只是單純的在檔案表項中維護了當前的鎖狀態。
強制鎖:只要加鎖了,別的程序不管使用何種方式,都無法寫入資料,除非你釋放鎖。
檔案鎖的核心結構
unix核心維護了乙個鎖表結構,用來實現對檔案的加鎖解鎖操作。在系統核心中乙個v節點代表了乙個檔案系統中的i節點也就代表了乙個檔案,每個v節點在系統核心中是全域性唯一的,v節點中存放了指向該檔案的鎖表結構的鎖表指標。
每個程序在對檔案進行加鎖解鎖的動作時,系統核心會收集所有程序對檔案所加的鎖,以鍊錶的形式進行儲存,鎖鏈表中每個節點都是乙個對該檔案某區域所加的鎖資訊。任何程序對檔案進行加鎖,系統都會遍歷該檔案對應的鎖表,發現鎖衝突,則阻塞或報錯,否則將鎖插入鎖表中。當程序進行解鎖時,系統則會將該鎖從鍊錶中刪除。
在乙個程序中,如果多個檔案描述符引用同乙個檔案,只要關閉其中任何乙個檔案描述符,該程序對該檔案所加的所有的鎖都會被釋放掉。
MySQL 共享排他鎖 mysql 共享排他鎖
1 基礎知識 共享鎖又叫s鎖 share locks 共享鎖就是多個事務對於同一資料可以共享一把鎖,都能訪問到資料,但是只能讀不能修改。排他鎖又叫x鎖 exclusive locks,記為x鎖 排他鎖就是不能與其他鎖並存,只有等待鎖釋放完成以後其他事務才能得到鎖。下面是共享鎖與排他鎖的互斥關係 s ...
共享鎖與排他鎖
共享鎖 s鎖 如果事務t對資料a加上共享鎖後,則其他事務只能對a再加共享鎖,不能加排他鎖。獲准共享鎖的事務職能讀取資料,不能修改資料。排他鎖 x鎖 如果事務t對資料a加上排他鎖後,則其他事務不能在對a加任何型別的封鎖。獲准排他鎖的事務既能讀取資料,也能修改資料。資料庫死鎖的原因 若干事務相互等待對方...
Mysql共享鎖 排他鎖
我之前專程寫了mysql中myisam和innodb區別 和mysql儲存引擎 這裡主要寫一些影響鎖相關的內容 mysql 在5.5之前預設使用 myisam 儲存引擎,之後使用 innodb 檢視當前儲存引擎 show variables like storage engine myisam 運算...