首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

linux文件锁解决方案

2014-01-14 
linux文件锁在看《linux程序设计 第四版》“7.2文件锁定”这一章节时自己编写了一个验证程序,目的是想测试文件

linux文件锁
在看《linux程序设计 第四版》“7.2文件锁定”这一章节时自己编写了一个验证程序,目的是想测试文件某个区域设置共享锁之后,不能再在这块区域内设置独占锁。
程序大体思路是这样的:
让程序lock1在文件的某个区域加共享锁,然后进入死循环;让程序lock2在这个文件的同样区域加独占锁。
想要得到的结果是程序lock2永远不能够在该文件的这块区域成功加独占锁。但是运行的结果却是lock2第一次尝试设置独占锁失败,但是第2次尝试却成功了,这让我有点搞不懂了。希望大神能够赐教,谢谢。代码如下:
locktest.txt
aaaaa
bbbbb
ccccc
ddddd
eeeee
fffff

lock1.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/file.h>

int main()
{
//int clock = 0;
int num = 0;
int n = 0;
int i;
char buf[20];
int file = open("locktest.txt",O_RDWR);
if(file == -1)
{
fprintf(stderr,"locktest.txt open failed\n");
return;
}
fprintf(stderr,"\nlock1 file open sucess!");
struct flock flockTemp;
memset(&flockTemp,0,sizeof(flock));
fprintf(stderr,"\nflock init done!");
flockTemp.l_type = F_RDLCK;//设置共享锁
flockTemp.l_whence = SEEK_SET;//文件的第一个字节
flockTemp.l_start = 6;//文件的第二行
flockTemp.l_len = 10;
flockTemp.l_pid = -1;
fprintf(stderr,"\nlock1 = %d",getpid());
while(fcntl(file,F_SETLK,&flockTemp) == -1)
{
fprintf(stderr,"lock1获取读锁失败\n");
//检查失败的原因是不是有其它进程加了锁
if(fcntl(file,F_GETLK,&flockTemp) != -1 && (flockTemp.l_pid != -1))
{
fprintf(stderr,"进程%d获得了%d\n",flockTemp.l_pid,flockTemp.l_type);
}
else
{
fprintf(stderr,"lock1获取读锁失败\n");
return;
}
}
fprintf(stderr,"lock1获取读锁成功\n");
while(1)
{
num++;
sleep(1);
}
/*lseek(file,6,SEEK_SET);
n = read(file,buf,12);
for(i = 0; i < n; i++)
{
fprintf(stderr, "%c ",buf[i]);
}

close(file);*/

}


lock2.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>


int main()
{
int clock = 0;
int n = 0;
int i;
char *str = "ggggg\nhhhhh\n";
//memset(buf,'1',20);
sleep(10);
int file = open("locktest.txt",O_RDWR);
if(file == -1)
{
fprintf(stderr,"locktest.txt open failed\n");
return;
}
struct flock flockTemp;
memset(&flockTemp,0,sizeof(flockTemp));
flockTemp.l_type = F_WRLCK;
flockTemp.l_whence = SEEK_SET;//文件的第一个字节
flockTemp.l_start = 6;//文件的第二行
flockTemp.l_len = 10;
flockTemp.l_pid = -1;
fprintf(stderr,"\nlock2 = %d",getpid());

while(fcntl(file,F_SETLK,&flockTemp) == -1)
{
fprintf(stderr,"lock2获取写锁失败\n");
//检查失败的原因是不是有其它进程加了锁
if((fcntl(file,F_GETLK,&flockTemp) != -1) && (flockTemp.l_pid != -1))
{
if(flockTemp.l_type == 0)
fprintf(stderr,"进程%d获得了读锁\n",flockTemp.l_pid);
else if(flockTemp.l_type == 1)
fprintf(stderr,"进程%d获得了写锁\n",flockTemp.l_pid);

}
else
{//其它原因,退出
fprintf(stderr,"lock2获取写锁失败......\n");
return;

}
}
fprintf(stderr,"lock2获取写锁成功......\n");
lseek(file,6,SEEK_SET);
n = write(file,str,12);
for(i = 0; i < n; i++)
{
fprintf(stderr, "%c ",str[i]);
}
close(file);

}


在ubuntu12.04下运行:
./lock1 &
./lock2
运行结果如下:
lock1 file open sucess!
flock init done!
lock1 = 14022lock1获取读锁成功

smile@smile-desktop:~/ispace/cspace/lock$ 
smile@smile-desktop:~/ispace/cspace/lock$ ./lock2

lock2 = 14024lock2获取写锁失败
进程14022获得了读锁
lock2获取写锁成功......
g g g g g 
 h h h h h 

[解决办法]
lock2.c实现有问题,检查失败的原因时候,你使用fcntl获取了锁信息,使flockTemp发生了变化(l_type变为了F_RDLCK, l_pid变为了lock1的进程号),而重新fcntl加锁时加的是读锁,可以把lock2修改以下,在获取锁的处理后

flockTemp.l_type = F_WRLCK;

热点排行