转自:使用FD_CLOEXEC实现close-on-exec,关闭子进程无用文件描述符

我们经常会碰到需要fork子进程的情况,而且子进程很可能会继续exec新的程序。这就不得不提到子进程中无用文件描述符的问题!

fork函数的使用本不是这里讨论的话题,但必须提一下的是:子进程以写时复制(COW,Copy-On-Write)方式获得父进程的数据空间、堆和栈副本,这其中也包括文件描述符。刚刚fork成功时,父子进程中相同的文件描述符指向系统文件表中的同一项(这也意味着他们共享同一文件偏移量)。

接着,一般我们会调用exec执行另一个程序,此时会用全新的程序替换子进程的正文,数据,堆和栈等。此时保存文件描述符的变量当然也不存在了,我们就无法关闭无用的文件描述符了。所以通常我们会fork子进程后在子进程中直接执行close关掉无用的文件描述符,然后再执行exec。

但是在复杂系统中,有时我们fork子进程时已经不知道打开了多少个文件描述符(包括socket句柄等),这此时进行逐一清理确实有很大难度。我们期望的是能在fork子进程前打开某个文件句柄时就指定好:“这个句柄我在fork子进程后执行exec时就关闭”。其实时有这样的方法的:即所谓的 close-on-exec。

close-on-exec的实现只需要调用系统的fcntl就能实现,很简单几句代码就能实现:

int fd=open("foo.txt",O_RDONLY);
int flags = fcntl(fd, F_GETFD);
flags |= FD_CLOEXEC;
fcntl(fd, F_SETFD, flags);

这样,当fork子进程后,仍然可以使用fd。但执行exec后系统就会字段关闭子进程中的fd了。

-------------------------------------------------------- 分割线 ------------------------------------------------------------------------------------

最近好好看了一下open函数,其中flags参数可以传入O_CLOEXEC标记 [注意:Linux 2.6.23才开始支持此标记]

这样就可以一步实现上面的提到的close-on-exec的效果。

最新文章

  1. 新开了一个ABP交流的QQ群(579765441 ),欢迎加入
  2. Scrum Meeting 14-20151227
  3. lucene 建立索引的不同方式
  4. wamp2.4允许局域网访问,如Android模拟器和手机
  5. 查询SQL SERVER数据库日志工具
  6. <!--[if lt IE]>
  7. BZOJ 3243 向量内积
  8. vue.js的devtools安装
  9. 初学MVC
  10. OCP读书笔记(23) - 题库(ExamC)
  11. Java中的懒汉式单例与饿汉式单例实例详解
  12. 201621123031 《Java程序设计》第14周学习总结
  13. ifram 局部刷新,不刷新父级
  14. bgfx入门练习3——编译自定义Shader
  15. Latex中cls和sty文件有何区别?
  16. LinkedHashMap 实现总结
  17. 隐藏Android下的虚拟按键
  18. TensorFlow 同时调用多个预训练好的模型
  19. python文件上传的三种方式
  20. How to Install PhantomJS on Ubuntu 16.04

热门文章

  1. iOS数据库操作(使用FMDB)
  2. Linux下使用split按行数进行切割
  3. 常见的 HTTP 状态代码及原因
  4. Android 中AlarmManager升级4.2
  5. ORA-12537:TNS连接已关闭
  6. Objective-C:NSSet和NSMutbaleSet的用法
  7. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:2.搭建环境-2.10.配置用户NTF服务
  8. Vue组件开发实例(详细注释)
  9. 阿里云RDS(云数据库)之产品简介
  10. J2EE开发工作中遇到的异常问题及解决方法总结