在看《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获取写锁成功...... lock2.c实现有问题,检查失败的原因时候,你使用fcntl获取了锁信息,使flockTemp发生了变化(l_type变为了F_RDLCK, l_pid变为了lock1的进程号),而重新fcntl加锁时加的是读锁,可以把lock2修改以下,在获取锁的处理后
flockTemp.l_type = F_WRLCK;
|