文件锁用于多个进程同时对一个文件进行操作而产生的问题的处理,我们在实际应用中这种情况经常会遇到,具体的情况有以下几种:
1)一个进程在写文件,同时另一个进程也要对该文件进行写操作;
2)一个进程在写文件,同时另一个进程要对这个文件进行读取操作;
文件加锁规则:
有读锁的时候可以再加读锁,不能再加写锁;有写锁的时候,不能加任何锁。加读锁时,该描述符必须是读打开,加写锁时,该描述符必须是写打开。
关于文件锁的三个函数:lockf(),fcntl(),flock()。这篇当中我们主要对lockf()这个函数讨论。
一、lockf()
#include<unistd.h>
int lockf(int fd,int cmd,off_t len);
off_t就是long型。
第一个参数:文件描述符;
第二个参数:lockf指定功能,参数值为:
#define F_ULOCK 0(释放文件锁)
#define F_LOCK 1(文件上锁)
#define F_TLOCK 2(测试互斥锁定区域)
#define F_TEST 3(测试区域)
第三个参数:要锁定或解锁的连续字节数。一般为0代表整个文件;
下面看下代码怎么验证文件加写锁(独占锁)
//write_lockf.c
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/file.h>
#include<stdlib.h>
int main()
{
int fp, ret, num;
char buff[100];
if ((fp = open("1.txt",O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0){
printf("open file error:%s\n",strerror(errno));
exit(-1);
}
if ((ret = lockf(fp,F_LOCK,(off_t)0)) == -1){
printf("lockf error:%s\n",strerror(errno));
exit(-1);
}
num = 1;
for (;;){
memset(buff,0,sizeof(buff));
sprintf(buff,"%d:%d|",getpid(),num++);
write(fp,buff,strlen(buff));
if (num > 20) break;
usleep(500000);
}
close(fp);
return 0;
}
$gcc write_lockf.c -o write_lockf
在两个终端下同时运行,再在第三个终端上用vi查看1.txt文件写入的情况,在vi里面通过:e命令查看文件更新情况,这时候发现只有一个进程一直在写文件,另一个进程就会阻塞在那儿一直等到前一个进程释放文件锁之后才进行写文件操作。
这种用lockf()加锁是一种比较简单的方法。lockf()操作简化了fcntl()的接口,我们在下一篇中将继续讨论文件锁fcntl()的用法。