记录锁(record locking)的功能是:

当第一个进程正在读或修改文件的某个部分时,使用记录锁可以阻止其他进程修改同一文件区。

“记录”这个词是一种误用,因为UNIX系统内核根本没有使用文件记录这种概念。

一个更适合的术语可能是字节范围锁 (byte-range locking),因为它锁定的只是文件中的一个区域(也可能是整个文件)。

Linux记录锁(文件锁)_#include

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) */
};

Linux记录锁(文件锁)_#define_02

Linux记录锁(文件锁)_#include_03

实例代码:

#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