記錄鎖【轉】
記錄鎖 第二種方式可以實現只鎖檔案的某個部分,並且可以靈活的選擇是阻塞方式還是立刻返回方式。
記錄鎖通過系統呼叫 fcntl來實現 #include <fcntl.h> int fcntl(int fd, int command, long arg);
struct flock { short l_type; // 鎖的型別 short l_whence;// 鎖的起始 off_t l_start;// 鎖的起始偏移,與l_whence相關 off_t l_len; // 鎖住多少位元組 off_t l_pid; // 擁有鎖的程序pid }
呼叫fcntl進行加鎖的操作時,arg是指向結構體flock的指標。 l_type表示加鎖的型別,它可以是以下值: F_RDLCK 讀鎖(共享鎖) F_WRLCK 寫鎖(獨佔鎖) F_UNLCK 釋放鎖
引數l_whence和l_start表示鎖的起始地址,含義與lseek中的同名引數相同。 l_whence為以下三個值之一: SEEK_SET: 從檔案開始計算 SEEK_CUR: 從當前計算 SEEK_END:從檔案末尾計算
引數 l_len表示鎖的長度是多少位元組,如果為0.表示鎖一直延伸到檔案按的末尾。 l_pid: 僅在查詢鎖的時候才用,它是這個鎖的擁有者的程序pid
fcntl有三個命令和加鎖有關,操作通過引數command來傳遞,它可以是以下的三個值之一: F_SETLK: 按照arg進行加鎖和解鎖的處理,如果因為衝突不能上鎖,立刻返回並且errno被設定為EAGAIN。 如果l_type是F_UNLCK,已存在的鎖被釋放。 F_SETLKW:相當於阻塞式的F_SETLK(W的含義是wait)。如果要上鎖的區域被其他程序鎖住,使申請不能馬上成功,則進入睡眠, 等待原來的鎖被釋放,在上鎖成功後返回,如果在程序阻塞時有訊號發生,返回並且errno被設為EAGAIN F_GETLK:檢查是否可以申請由arg決定的鎖。如果不和別的程序已經存在的鎖發生衝突,arg指向的結構flock中的l_type被賦為 F_UNLCK,其餘的成員不變。如果不能給與鎖,l_pid被賦為發生衝突的程序的pid。這兩種情況下函式都返回0。
下面是一些關於記錄鎖的規則: 1)鎖可以延伸到檔案按目前的結尾之後,但是不能擴充套件到檔案頭之前,也不能從檔案頭之前開始。 2)如果l_len為0,鎖得到最大長度的延伸,這是我們可以從檔案的任何地方開始,向後鎖住所有的檔案資料,並鎖住以後新增到 檔案末尾的資料,不管新增多少資料。 3)要鎖住整個檔案,設l_start為0,l_whence為SEEK_SET,l_len為0。 4)如果一塊區域被一個程序加了讀鎖,則另外的程序可以再給它加上讀鎖,但是不能加寫鎖。(共享鎖)。 如果一塊區域被一個程序加了些鎖,則它不能為另外的程序加上讀鎖或寫鎖(獨佔鎖)。
5)鎖的釋放: 當程序終止時,它所有的鎖都會被釋放(不同與檔案鎖)。 當檔案描述符關閉時,在這個程序中,加在該檔案描述符上的所有鎖被釋放。