Linux文件锁
Posted uestclr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux文件锁相关的知识,希望对你有一定的参考价值。
当多个进程同时操作一个文件时,必然会引发数据之间的冲突,例如一个进程在读文件,另一个进程却在写文件,或者是两个进程都在同时写文件。为了使得多个进程操作文件时的安全性,可以使用文件锁。
文件锁允许多个进程同时读文件(因为读操作并没有影响文件的内容),但不允许同时写,一些读一些写也不行,所以文件锁分为读锁和写锁。读锁的效果是允许其他进程读文件,但不允许其他进程写文件,而写锁的效果是即不允许其他进程读文件,也不允许其他进程写文件。
文件锁的代码实现主要依赖于函数fcntl()和一个结构体struct flock来实现。
fcntl(int fd,F_SETLK/F_SETLKW,struct flock*),第一个参数时操作文件的文件描述符,第二个参数时一个宏,代表锁定的方式,F_SETLK表示锁定失败就返回-1,而F_SETLKW表示锁不上就一直等待,等到其他进程释放锁时候才加锁。一般有两种选择,第三个参数是一个锁结构指针。
struct flock
short l_type;//锁的类型,包括读锁,写锁和释放锁
short l_whence;//锁定起始点的参考位置
off_t l_start;//锁定起始点的偏移量
off_t l_len;//锁定区域的大小,锁定的长度
pid_t l_pid;//锁定进程的PID,只有GETLK用的到,给-1即可
;
l_type锁的类型:F_RDLCK/F_WRLCK/F_UNLCK(包括读锁,写锁,和释放锁)
l_whence:SEEK_SET/SEEK_END/SEEK_CUR(分别表示从头开始,从末尾开始和从当前位置开始偏移)
注意:文件锁不是锁定整个文件,而是锁定文件的一部分。锁定部分由l_whence/l_start/l_len三个联合决定;
比如:l_whence选择SEEK_SET,l_start = 10,l_len = 20;锁定的区域就是:第11个到第30个(文件头偏移10,锁定20个字节)。
void main()
int fd = open("a.txt",O_RDWR);
if (fd == -1) perror("open"),exit(-1);
struct flock lock;
lock.l_type = F_RDLCK;//写锁
lock.l_whence = SEEK_SET;
lock.l_start = 10;
lock.l_len = 20;
lock.l_pid = -1;
int res = fcntl(fd,F_SETLK,&lock);
if (res == -1) printf("上锁失败!\\n");
else printf("锁定成功\\n");
sleep(15);
close(fd);
而读写锁的正确使用方式是在读之前加一把读锁,而在写之前加一把写锁。文件锁并不能锁定读写的函数read()/write(),只能阻止其他进程的加锁行为,导致其他进程加不上锁,因此:文件锁的正确用法,在调用read函数之前应该加上一把读锁,在调用之前加一个写锁,读写完毕之后马上释放锁;
void main()
int fd = open("a.txt",O_RDWR);
if (fd == -1) perror("open"),exit(-1);
struct flock lock;
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 10;
lock.l_len = 5;
lock.l_pid = -1;
int res = fcntl(fd,F_SETLK,&lock);
if (res == -1) printf("上锁失败!\\n");
else printf("锁定成功,开始读文件\\n");
char buf[5] = ;
read(fd,buf,sizeof(buf));
sleep(25);
printf("读完了,释放锁\\n");
lock.l_type = F_UNLCK;
fcntl(fd,F_SETLK,&lock);
sleep(10);
close(fd);
printf("%s\\n",buf);
上面的代码加了读锁,下面是写的代码。
#include "myfile.h"
void main()
int fd = open("a.txt",O_RDWR);
if (fd == -1) perror("open"),exit(-1);
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 10;
lock.l_len = 20;
lock.l_pid = -1;
int res = fcntl(fd,F_SETLK,&lock);
if (res == -1)
printf("上锁失败!\\n");
else //只有上锁成功才能进行读写操作
printf("锁定成功\\n");
write(fd,"ooooo",5);
close(fd);
可以测试,在读的过程没有结束之前,就是读锁没有释放之前,去进行写操作的话,写锁是无法成功锁上的,而只有当读锁被释放了之后,才能成功加上写锁。
上面所有代码都必须包含myfile.h头文件,这个头文件的内容是:
#ifndef _MYFILE_H
#define _MYFILE_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#endif
以上是关于Linux文件锁的主要内容,如果未能解决你的问题,请参考以下文章