Linux C 学习之 - fcntl 函数
来源:互联网 发布:做账软件哪个好 编辑:程序博客网 时间:2024/05/16 05:59
小编在这片文章中就不说 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函数来加锁文件,网上有人说读写锁只能同时存在一个,这是不全面的,进过上面的测试代码可知。
在这里我把我今天用这个函数遇到的一些问题列举下,如有写的不对的地方,还望各位高手指正,不甚感激!
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 == 当前占用锁的进程。
0
上一篇:网络上的一些C面试题,做个摘录
下一篇:SPEC 文件详解
相关热门文章
- 广州传智播客最给力的Java培训...
- 广州传智播客网页平面设计,风...
- sar命令详解
- 广州传智播客老师分享:学了.N...
- 东鹏洁具营销三大趋势 售后服...
- test123
- 编写安全代码——小心有符号数...
- 使用openssl api进行加密解密...
- 一段自己打印自己的c程序...
- sql relay的c++接口
- linux inode中磁盘地址列表有...
- LNMP 老是会出现502?
- suse 运用一个shell获取本机和...
- 虚拟机 unix 配置ip
- hp-un 主机新系统读不到磁盘阵...
给主人留下些什么吧!~~
评论热议
0 0
- Linux C 学习之 - fcntl 函数
- Linux C 学习之 - fcntl 函数
- linux函数之fcntl
- linux之fcntl函数解析
- Linux系统函数之fcntl函数
- linux c语言 fcntl函数说明
- linux 0.11 内核学习 -- fcntl.c
- linux C学习之 sys/types.h和fcntl.h的作用
- linux fcntl()函数
- Linux fcntl函数详解
- Linux fcntl函数详解
- Linux fcntl函数详解
- linux fcntl函数说明
- Linux fcntl函数详解
- linux fcntl函数
- Linux fcntl函数详解
- Linux fcntl函数详解
- linux fcntl()函数
- Linux Shell之常用快捷键
- Linux Shell 文件重定向 小觑
- OSCache简单例子
- 《unix环境高级编程》学习之 --- fread 函数
- 网络上的一些C面试题,做个摘录
- Linux C 学习之 - fcntl 函数
- AUPE学习第二章------UNIX标准化及实现
- SPEC 文件详解
- 《unix环境高级编程》学习之 --- vfork()
- 王维:送綦毋潜落第还乡
- Effective C++ 3.资源管理
- SQL2005触发器
- STM32 多通道ADC采样,采用Timer1进行采样率控制,利用DMA进行传输
- 导航引擎结构分析之一
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
新页进销存
象过河进销存手机版
服装进销存管理软件
进销存 手机版 免费
进销存app
手机进销存软件哪个好
手机进销存管理系统
进销存软件免费版
五金进销存管理软件
出入库管理软件
进销存软件哪个好用
中科院认可国际商友圈吗
中科院承认内蒙古国际商友圈
友善
友善名言
友善作文
友善的名言
友善手抄报
友善英文
友善的意思
友善的英文
友善拼音
夏友善
友善事例
诚信友善
友善的故事
友善的拼音
关于友善的名言
友善让生活更美好作文
关于友善的故事
关于友善的作文
关于友善的理解
关于友善的名言警句
夏家三千金之友善友善
文明富强敬业诚信友善
友嘉信息
天上友嘉
友嘉集团
友嘉机床
友嘉
友嘉加工中心