




已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
fcntl 和 select 函数彻底搞明白 第一、fcntl 函数详细使用 fcntl 有强大的功能,它能够复制一个现有的描述符,获得/设置文件描述符标记, 获得/设置文件状态标记,获得/设置异步 I/O 所有权,获得 /设置纪录锁。 当多个用户共同使用,操作一个文件的情况,Linux 通常采用的方法就是给文 件上锁,来避免共享资源产生竞争的状态。 fcntl 文件锁有两种类型:建议性锁和强制性锁 建议性锁是这样规定的:每个使用上锁文件的进程都要检查是否有锁存 在,当然还得尊重已有的锁。内核和系统总体上都坚持不使用建议性锁,它们 依靠程序员遵守这个规定。 强制性锁是由内核执行的。当文件被上锁来进行写入操作时,在锁定该 文件的进程释放该锁之前,内核会阻止任何对该文件的读或写访问,每次读或 写访问都得检查锁是否存在。 使用 fcntl 文件锁进行 I/O 操作必须小心:进程在开始任何 I/O 操作前如 何去处理锁,在对文件解锁前如何完成所有的操作,是必须考虑的。如果在设 置锁之前打开文件,或者读取该锁之后关闭文件,另一个进程就可能在上锁/解 锁操作和打开/关闭操作之间的几分之一秒内访问该文件。当一个进程对文件加 锁后,无论它是否释放所加的锁,只要文件关闭,内核都会自动释放加在文件 上的建议性锁(这也是建议性锁和强制性锁的最大区别), 所以不要想设置建 议性锁来达到永久不让别的进程访问文件的目的(强制性锁才可以)_;强制性 锁则对所有进程起作用。 可以用 fcntl 函数改变一个已打开的文件的属性, 可以重新设置读、写、追 加、非阻塞等标志(这些标志称为 File StatusFlag),而不必重新 open 文件。 #include #include int fcntl(int fd, int cmd); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, struct flock *lock); 这个函数和 open 一样,也是用可变参数实现的,可变参数的类型和个数取决于前 面的 cmd 参数。 文件锁包括了 建议性锁 和 强制性锁。 建议性锁要求每个上锁的文件的进程都要检查是否有锁存在,并且尊重已有的 锁,在一般情况下,内核和系统都不使用建议性锁。 强制性锁是由内核执行的锁,当一个文件被上锁进行读写操作的时候,内核将 阻止其他任何文件对其进行读写操作。每次读写操作都要检查是否有锁存在。 在 Linux 中实现上锁的函数有 lock()和 fcntl()。 lock()用于对文件施加建议性锁 fcntl()用于对文件施加建议性锁和强制性锁都行。同时还可以对文件某一条纪录 进行上锁,也就是记录锁。 记录锁分为 读取锁(共享锁,它能够使多个进程都能在文件的同一部分建立读 取锁) 和 写入锁(排斥锁,在任何时刻只能有一个进程在文件的某部分建立 写入锁。)。 fcntl 函数原型 #include #include #include int fcntl(int fd, /文件描述符 int cmd , /不同的命令 struct flock *lock) /设置记录锁的具体状态 cmd 取值: F_DUPFD 复制文件描述符 F_GETFD 获得 fd 的 close-on-exec 标志 F_SETFD 设置 close-on-exec 标志 F_GETFL 获得 open 设置标志 F_SETFL 设置 lock 描述的标志 F_GETLK 测试该锁是否被另外一把锁排斥 F_SETLKW 如果存在其他锁,则调用进程睡眠,如果捕捉到信号则睡眠中断 F_GETOWN 检索收到的 SIGIO 和 SIGURG 信号的进程号或者进程组号 F_SETOWN 设置进程号或进程组号 这里的 lock 结构体如下: struct flock short l_type; /*F_RDLCK(读取锁),F_WRLCK(写入锁),F_UNLCK(解锁) */ off_t l_start; /*相对偏移量(字节)*/ short l_whence; /*SEEK_SET ,SEEK_CUR ,SEEK_END */ off_t l_len; /*加锁区域长度*/ pid_t l_pid; 成功:0 出错:-1 提示:如果加锁整个文件通常的方法是将 l_start 设置为 0,l_whence 设置为 SEEK_SET, l_len 设置为 0。 下面的例子使用 F_GETFL 和 F_SETFL 这两种 fcntl 命令改变 STDIN_FILENO 的属性上 O_NONBLOCK 选项, 实现非阻塞读终端的功能。 用 fcntl 改变 File Status Flag #include #include #include #include #include #define MSG_TRY “try againn“ int main(void) char buf10; int n; int flags; flags = fcntl(STDIN_FILENO, F_GETFL); flags |= O_NONBLOCK; if (fcntl(STDIN_FILENO, F_SETFL, flags) = -1) perror(“fcntl“); exit(1); tryagain: n = read(STDIN_FILENO, buf, 10); if (n #include #include int main(int argc, char * argv) char buf10 = “; read(0, buf, 9); /* 从标准输入 0 读入字符 */ fprintf(stdout, “%sn“, buf); /* 向标准输出 stdout 写字符 */ return 0; /* *上面和下面的代码都可以用来从标准输入读用户输入的 9 个字符* */ #include #include #include int main(int argc, char * argv) char buf10 = “; fread(buf, 9, 1, stdin); /* 从标准输入 stdin 读入字符 */ write(1, buf, strlen(buf); return 0; 继续上面说的 select,就是用来监视某个或某些句柄的状态变化的。 select 函数原型如下: int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 函数的最后一个参数 timeout 显然是一个超时时间值,其类型是 struct timeval *,即一个 struct timeval 结构的变量的指针,所以我们在程序里要申明 一个 struct timeval tv;然后把变量 tv 的地址 /* seconds */ long tv_usec; /* microseconds */ ; 第 2、3、4 三个参数是一样的类型: fd_set *,即我们在程序里要申明几个 fd_set 类型的变量,比如 rdfds, wtfds, exfds,然后把这个变量的地址 /* 先申明一个 fd_set 集合来保存我们要检测的 socket 句柄 */ struct timeval tv; /* 申明一个时间变量来保存时间 */ int ret; /* 保存返回值 */ FD_ZERO( /* 用 select 函数之前先把集合清零 */ FD_SET(socket, /* 把要检测的句柄 socket 加入到集合里 */ tv.tv_sec = 1; tv.tv_usec = 500; /* 设置 select 等待的最大时间为 1 秒加 500 毫秒 */ ret = select(socket + 1, /* 检测我们上面设置到集合 rdfds 里的句柄是否有可读信息 */ if(ret maxfd) maxfd = sa; if(sb maxfd) maxfd = sb; if(sc maxfd) maxfd = sc; 然后调用 select 函数: ret = select(maxfd + 1, /* 注意是最大值还要加 1 */ 同样的道理,如果我们要检测用户是否按了键盘进行输入,我们就应该把标准 输入 0 这个句柄放到 select 里来检测,如下: FD_ZERO( FD_SET(0, tv.tv_sec = 1; t
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年乡村旅游与非物质文化遗产传承报告
- 玛利亚vip门诊协议书
- 聘用退休人员签合同范本
- 猪场合作养殖协议书范本
- 首封人债权转让合同范本
- 淘宝与快递合作合同范本
- 汽油餐饮车转让合同范本
- 涂料机低价转让协议合同
- 签订借款合同后的协议书
- 篮球互租合同协议书范本
- 企业车间公司生产部年中工作汇报工作总结PPT图文课件
- 林木育种学复习试题及答案解析
- GB/T 532-2008硫化橡胶或热塑性橡胶与织物粘合强度的测定
- GB/T 3633-1995钢结构用扭剪型高强度螺栓连接副技术条件
- GB/T 32891.2-2019旋转电机效率分级(IE代码)第2部分:变速交流电动机
- GB/T 30773-2014气相色谱法测定酚醛树脂中游离苯酚含量
- 2022-2023学年甘肃省定西市成考专升本高等数学一自考预测试题(含答案)
- 电梯维护保养规则
- (新版)心理倾听师资格考试备考题库(精简250题)
- 宋龙渊道德经讲义
- 八年级初二升九年级英语试卷及答案
评论
0/150
提交评论