linux fcntl函数,Linux C 学习之 - fcntl 函数

小编在这片文章中就不说 fcntl 如何使用了,如果有不明白的地方,请转到去问度娘:“ Linux fcntl”, 她会告诉我们一大堆。

在这里我把我今天用这个函数遇到的一些问题列举下,如有写的不对的地方,还望各位高手指正,不甚感激!

include #include #include 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 #include #include 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 == 当前占用锁的进程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值