概述
文件级的锁:对整个文件加锁,flock系统调用
文件内范围的锁:对文件的某个范围加锁,fcntl库函数
1. flock
flock是系统调用,加的建议锁
https://man7.org/linux/man-pages/man2/flock.2.html
tips:
flock的锁的语义:获取到的锁是与打开的文件描述符,而不是文件描述符或者inode相关联
(1)对于open同一个文件多次,获取到的不同fd,flock会认为是不同的,所以再加flock会block
(2)flock创建的锁是和fd相关的,所以复制dup(fd)和fork产生的fd,都是同一把锁
demo:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
int main (int argc, char ** argv)
{
int ret;
int fd1 = open("tmp.txt",O_RDWR);
int fd2 = open("tmp.txt",O_RDWR);
//int fd2 = dup(fd1);
printf("fd1: %d, fd2: %dn", fd1, fd2);
ret = flock(fd1,LOCK_EX);
printf("get lock1, ret: %dn", ret);
ret = flock(fd2,LOCK_EX|LOCK_NB);
printf("get lock2, ret: %dn", ret);
return 0;
}
2. fcntl
是GNU C库函数,既可以加建议锁和强制性锁
https://man7.org/linux/man-pages/man2/fcntl.2.html
#include <fcntl.h>
struct flock {
short l_type; // F_RDLCK,F_WRLCK,F_UNLCK
short l_whence; // SEEK_SET,SEEK_CUR,SEEK_END,起始位置,文件的当前偏移量,结尾位置
off_t l_start; // offset where the lock begins
off_t l_len; // number of bytes to lock
pid_t l_pid; // process preventing our lock(only F_GETLK only)
};
struct flock flockinfo;
fcntl(fd, F_SETLK, &flockinfo)
F_GETLK:检测是否可以获取指定区域的锁,实际并不获取这把锁,如果可以返回的l_type是F_UNLCK
F_SETLK:更新锁,如果有冲突返回EAGAIN
F_SETLKW:更新锁,如果有冲突,则阻塞直到锁的请求被满足
demo:
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_len = 100;
lock.l_pid = getpid();
const char* fname = "test.txt";
int fd = open(fname, O_RDWR);
if (fd < 0) {
printf("open err: fname %sn", fname);
return -1;
}
int ret = fcntl(fd, F_SETLK, &lock);
if (ret == 0) {
printf("ltyp %d range(%d:%d)n", lock.l_type, lock.l_start, lock.l_len);
} else {
printf("error: ltyp %d range(%d:%d)n", lock.l_type, lock.l_start, lock.l_len);
}
close(fd);
return 0;
}
3. flock和fcntl的区别和联系
结论1:
两者判断锁是否冲突的区别:
flock的owner是内核态的open fd,判断是否冲突也是根据owner,如果owner相同则可以递归申请。
这样解释:多次open同一个文件内核有两个fd,所以owner不同,再加flock会锁住,dup则在内核态还是一个owner,不会冲突
Fcntl的owner是进程,不是fd也不是inode
结论2:
两者的联系:
flock创建的锁和fcntl创建的锁之间的交互是未定义的行为,因此应用程序应该只使用其中一种文件加锁方法。——《linux-unix系统编程手册》
reference:
[1] https://www.jianshu.com/p/8b355893f709
[2] https://yxkemiya.github.io/2019/08/19/file-lock/
[3] 《linux-unix系统编程手册》55.2和55.3章节
[4] 《unix环境高级编程》14.3章节
最后
以上就是高挑康乃馨为你收集整理的文件锁-flock和fcntl的全部内容,希望文章能够帮你解决文件锁-flock和fcntl所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复