Linux記錄鎖(檔案鎖)
阿新 • • 發佈:2018-12-11
記錄鎖(record locking)的功能是:
當第一個程序正在讀或修改檔案的某個部分時,使用記錄鎖可以阻止其他程序修改同一檔案區。
“記錄”這個詞是一種誤用,因為UNIX系統核心根本沒有使用檔案記錄這種概念。
一個更適合的術語可能是位元組範圍鎖 (byte-range locking),因為它鎖定的只是檔案中的一個區域(也可能是整個檔案)。
struct flock { short l_type; /* 鎖型別: F_RDLCK, F_WRLCK, F_UNLCK */ short l_whence; /* 取值為SEEK_SET(檔案頭), SEEK_CUR(檔案當前位置), SEEK_END(檔案尾) */ off_t l_start; /* 相對於l_whence欄位的偏移量 */ off_t l_len; /* 需要鎖定的長度 */ pid_t l_pid; /* 當前獲得檔案鎖的程序標識(F_GETLK) */ };
例項程式碼:
#include <stdio.h> #include <pthread.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <sys/resource.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <syslog.h> #include <string.h> //對檔案進行上鎖 #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)) //判斷檔案能不能鎖 #define is_read_lockable(fd, offset, whence, len) \ lock_test((fd), F_RDLCK, (offset), (whence), (len)) #define is_write_lockable(fd, offset, whence, len) \ lock_test((fd), F_WRLCK, (offset), (whence), (len)) int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) { struct flock lock; int a = 852; lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */ lock.l_start = offset; /* byte offset, relative to l_whence */ lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ lock.l_len = len; /* #bytes (0 means to EOF) */ lock.l_pid = getpid(); //printf("%d \n", lock.l_pid); return(fcntl(fd, cmd, &lock)); } pid_t lock_test(int fd, int type, off_t offset, int whence, off_t len) { struct flock lock1; int a; lock1.l_type = type; /* F_RDLCK or F_WRLCK */ lock1.l_start = offset; /* byte offset, relative to l_whence */ lock1.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ lock1.l_len = len; /* #bytes (0 means to EOF) */ lock1.l_pid = getpid(); if (fcntl(fd, F_GETLK, &lock1) < 0) perror("fcntl error"); if (lock1.l_type == F_UNLCK) { return(0); /* false, region isn’t locked by another proc */ } return(lock1.l_pid); /* true, return pid of lock owner */ } int main(void) { int i = -1; int j = -1; int fd = -1; int pid = -1; char buf[30] = {"this is second\n"}; if ( (fd = open("myfile", O_RDWR) ) < 0) { perror("open"); exit(-1); } j = is_write_lockable(fd, 5, SEEK_SET, 1); //判斷有沒有鎖 if( j == 0 ) { printf("thid file have no lock \n"); printf("Now ,using file lock \n"); write_lock(fd, 5, SEEK_SET, 1); //上鎖 for(;;); //endless loop }else { printf("pid = %d using file lock\n", j); //output using file lock Processes ID } exit(0); }
結果:
終端1:
# ./a.out thid file have no lock Now ,using file lock
終端2:
# ps -au | grep a.out root 9942 103 0.0 4200 352 pts/1 R+ 09:25 0:13 ./a.out # ./a.out pid = 9942 using file lock