•什么是文件锁
•英文名:file lock,在同一时刻只允许一个进程对文件进行访问
•建议性锁:advisory locking,又称协同锁
–内核只提供加减锁以及检测是否加锁,不提供锁的控制与协调工作
–需要多进程相互检测确认的加锁机制
–A进程对一个操作的文件加了锁
–B进程同样可以对该文件进行读写操作
–只有当B进程也对该文件加锁,文件锁才能起到同步作用
–Linux一般使用建议锁,而Windows一般使用强制性锁
•强制性锁: mandatory locking
–进程对文件进行I/O操作是,内核内部会检测该文件是否被加锁
–A进程对一个操作的文件加了锁
–当B进程对该文件进行I/O操作时,内核若检测该文件加了强制锁,B进程的操作则会失败
•系统调用:flock
•函数原型:int flock (int fd, int operation);
•函数功能:给整个文件添加或解除一个建议锁
•函数参数:operation
–LOCK_SH:共享锁
–LOCK_EX:独占锁、排他锁
–LOCK_UN:移除锁
•TIPS
–Flock只提供加锁、解锁机制,不提供锁检查
–需要用户自己检测,达到多进程同步操作
–用户若不自己检测,同样可以对一个已经加锁的文件进行读写操作
•系统调用:fcntl
•函数原型: int fcntl (int fd, int cmd, … /* arg */ );
•函数功能:给文件(部分文件)进行加锁、解锁操作
•函数参数:cmd
–F_SETLK:非阻塞式申请锁
–F_SETLKW:阻塞式申请锁
–F_GETLK:获取锁的相关信息
•记录锁
–读锁F_RDLCK,写锁F_WRLCK,释放锁F_UNLCK
•系统调用:lockf
•函数原型:int lockf (int fd, int cmd, off_t len);
•函数功能:
–可以更细粒度地对文件进行加锁、解锁操作
–库函数lockf是对系统调用fcntl的封装
•函数参数:operation
–F_LOCK:对文件某一区域添加独占锁
–F_TLOCK:非阻塞式申请锁
–F_ULOCK:对文件某一区域解锁
示例flock
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
int main (void)
{
int fd, i;
char filename[] = "data.log";
extern int errno;
fd = open (filename, O_WRONLY | O_CREAT, 0666);
if (fd != -1)
{
printf ("open file %s success \n", filename);
printf ("pls input a num to lock the file.\n");
scanf ("%d", &i);
printf ("try to lock the file...\n");
if (flock (fd, LOCK_EX) == 0)
printf ("lock file success\n");
else
printf ("lock file failed\n");
write (fd, "hello", 5);
printf ("input a num to Unlock the file.\n");
scanf ("%d", &i);
if (flock (fd, LOCK_UN) == 0)
printf ("file unlock success\n");
else
printf ("file unlock failed\n");
while (1);
}
else
{
perror ("open");
exit (EXIT_FAILURE);
}
return 0;
}
示例fcntl
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
if (argc > 1)
{
int fd = open (argv[1], O_WRONLY | O_CREAT, 0666);
if (fd == -1)
{
perror ("open");
exit (-1);
}
static struct flock lock;
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
lock.l_pid = getpid();
printf ("trying lock %s ...\n", argv[1]);
int ret = fcntl (fd, F_SETLKW, &lock);
if (ret == 0)
{
printf ("lock %s succeed\n", argv[1]);
while (1);
}
}
return 0;
}
示例lockf
flock 和lockf 可以共同加锁,互不影响
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
int main (int argc, char *argv[])
{
int fd, ret;
int pid;
fd = open ("tmp.txt", O_RDWR | O_CREAT, 0666);
ret = flock (fd, LOCK_EX);
printf ("flock return ret:%d\n", ret);
ret = lockf (fd, F_LOCK, 0);
printf ("lockf return ret:%d\n", ret);
sleep (30);
return 0;
}