小编在这片文章中就不说 fcntl 如何使用了,如果有不明白的地方,请转到去问度娘:“ Linux fcntl”, 她会告诉我们一大堆。
在这里我把我今天用这个函数遇到的一些问题列举下,如有写的不对的地方,还望各位高手指正,不甚感激!
上面这段程序执行结果:
current descriptor flags: 0
current descriptor flags: 0
write lock failed: Bad file descriptor
错误的文件描述符,一时半会不知道什么原因,后面检查程序
这里 fd = open("txt", O_RDONLY); 打开文件只是以制度方式打开的,而我要去加一把写锁,当然出错了,于是改为 fd = open("txt", O_RDWR); 好了,把读锁和写锁都加上去了。
是不是没问题了,不然,在网上看到有人说读写锁只能同时存在一个,那这里为什么读写锁都加上去了呢? 好好想想,会不会是在同一个进程中既可以加读锁也可以加写锁,因为该文件资源都属于该进程,改进程想读就读,想写就写! 于是,咋们就来创建一个子进程。把上面的代码改了
current descriptor flags: 0
current descriptor flags: 0
child read lock failed
child write lock failed
果然,在子进程中,不能再次加锁了。
在想,读锁不是可以存在多个吗?怎么子进程中的读锁也失败了,会不会是因为父进程中有写锁,导致子进程加读写锁都失败了,把父子进程中的加写锁注释掉
再次编译,运行:
current descriptor flags: 0
current descriptor flags: 0
说明问题还真是因为父进程中有写锁。
那么如果父进程中有读锁,在子进程中加写锁是否成功呢?下面取消注释掉子进程中的加写锁:
current descriptor flags: 0
current descriptor flags: 0
child write lock failed
可见,即便父进程中没有写锁,子进程中也不能加写锁,因为父进程已经存在了读锁!
好了,先到此为止,做个总结
fcntl函数来加锁文件,网上有人说读写锁只能同时存在一个,这是不全面的,进过上面的测试代码可知。
阅读(1017) | 评论(0) | 转发(2) |
<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
在这里我把我今天用这个函数遇到的一些问题列举下,如有写的不对的地方,还望各位高手指正,不甚感激!
include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
int ret;
struct flock rflk, wflk;
fd = open("txt", O_RDONLY);
if(fd < 0) {
perror("open failed");
return 1;
}
ret = fcntl(fd, F_GETFD);
printf("current descriptor flags: %d\n", ret);
fcntl(fd, F_SETFD, 1);
printf("current descriptor flags: %d\n", ret);
rflk.l_type = F_RDLCK;
rflk.l_whence = SEEK_SET;
rflk.l_start = 0;
rflk.l_len = 10;
wflk = rflk;
wflk.l_type = F_WRLCK;
if(fcntl(fd, F_SETLK, &rflk) == -1) {
perror("read lock failed");
return 1;
}
if(fcntl(fd, F_SETLK, &wflk) == -1) {
perror("write lock failed");
return 1;
}
close(fd);
return 0;
}
上面这段程序执行结果:
current descriptor flags: 0
current descriptor flags: 0
write lock failed: Bad file descriptor
错误的文件描述符,一时半会不知道什么原因,后面检查程序
这里 fd = open("txt", O_RDONLY); 打开文件只是以制度方式打开的,而我要去加一把写锁,当然出错了,于是改为 fd = open("txt", O_RDWR); 好了,把读锁和写锁都加上去了。
是不是没问题了,不然,在网上看到有人说读写锁只能同时存在一个,那这里为什么读写锁都加上去了呢? 好好想想,会不会是在同一个进程中既可以加读锁也可以加写锁,因为该文件资源都属于该进程,改进程想读就读,想写就写! 于是,咋们就来创建一个子进程。把上面的代码改了
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
int ret;
struct flock rflk, wflk;
fd = open("txt", O_RDWR);
if(fd < 0) {
perror("open failed");
return 1;
}
ret = fcntl(fd, F_GETFD);
printf("current descriptor flags: %d\n", ret);
fcntl(fd, F_SETFD, 1);
printf("current descriptor flags: %d\n", ret);
rflk.l_type = F_RDLCK;
rflk.l_whence = SEEK_SET;
rflk.l_start = 0;
rflk.l_len = 10;
wflk = rflk;
wflk.l_type = F_WRLCK;
if(fcntl(fd, F_SETLK, &rflk) == -1) {
perror("read lock failed");
return 1;
}
if(fcntl(fd, F_SETLK, &wflk) == -1) {
perror("write lock failed");
return 1;
}
if(fork()) {
if(fcntl(fd, F_SETLK, &rflk) == -1) {
fprintf(stderr, "parent read lock failed\n");
}
if(fcntl(fd, F_SETLK, &wflk) == -1) {
fprintf(stderr, "parent write lock failed\n");
}
sleep(3);
} else {
sleep(1);
if(fcntl(fd, F_SETLK, &rflk) == -1) {
fprintf(stderr, "child read lock failed\n");
}
if(fcntl(fd, F_SETLK, &wflk) == -1) {
fprintf(stderr, "child write lock failed\n");
}
}
close(fd);
return 0;
}
编译执行结果为:
current descriptor flags: 0
current descriptor flags: 0
child read lock failed
child write lock failed
果然,在子进程中,不能再次加锁了。
在想,读锁不是可以存在多个吗?怎么子进程中的读锁也失败了,会不会是因为父进程中有写锁,导致子进程加读写锁都失败了,把父子进程中的加写锁注释掉
再次编译,运行:
current descriptor flags: 0
current descriptor flags: 0
说明问题还真是因为父进程中有写锁。
那么如果父进程中有读锁,在子进程中加写锁是否成功呢?下面取消注释掉子进程中的加写锁:
current descriptor flags: 0
current descriptor flags: 0
child write lock failed
可见,即便父进程中没有写锁,子进程中也不能加写锁,因为父进程已经存在了读锁!
好了,先到此为止,做个总结
fcntl函数来加锁文件,网上有人说读写锁只能同时存在一个,这是不全面的,进过上面的测试代码可知。
1、在同一进程可以加多次读锁,多次写锁,并且可以同时存在!
上次这里说错了,在同一进程中,锁也并不是同时存在的,而是后面加的锁会覆盖前面加的锁!(2013/1/24修改)
2、在不同进程中,如果进程A拥有读锁或写锁, 那么进程B只能有读锁,不能加写锁3、还需要注意的是,在上面加锁的时候我们把 fcntl 的第二个参数cmd 都置为 F_SETLK,如果把它换成 F_SETLKW,那么在不同进程间可同时加读写锁。假设进程A先拥有了某个锁,进程B想给自己加一把锁,那么就会等到进程A把锁释放掉!
4、如果调用 fcntl(fd, F_GETLK, &flk) 时,如果能够得到这样的锁,那么设置 flk.l_type == F_UNLCK, flk 其他成员值不变; 否则,如果不能得到这样的锁,重新设置 flk 的值,使 l_pid == 当前占用锁的进程。
相关热门文章
给主人留下些什么吧!~~
评论热议