我们经常会碰到需要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的效果。

使用FD_CLOEXEC实现close-on-exec,关闭子进程无用文件描述符相关推荐

  1. linux 关闭打开的文件描述符,关闭它们后重新打开stdout和stdin文件描述符

    Ambroz Bizja.. 39 您应该使用dup()和dup2()来克隆文件描述符. int stdin_copy = dup(0); int stdout_copy = dup(1); clos ...

  2. Linux下使用exec命令将文件与文件描述符关联

    在shell脚本下exec为系统自带的脚本命令,其作用是用来执行其他程序: 语法格式: exec (选项)(参数) 选项: -c:在当前环境下执行命令,即在当前shell脚本下执行,而不是打开一个新的 ...

  3. fork()子进程与父进程之间的文件描述符问题

    在C程序中,文件由文件指针或者文件描述符表示.ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O ...

  4. linux exec操作文件描述符

    linux每一个打开文件都会关联一个文件描述符,需要的时候我们可以使用exec命令指定一个大于3的数字作为文件 linux默认文件描述符 每打开一个shell就会打开默认的三个文件描述符描0,1,2, ...

  5. FORK()子进程对父进程打开的文件描述符的处理

    总的来说,子进程将复制父亲进程的数据段,BSS段,代码段,堆空间,栈空间和文件描述符.而对于文件技术符关联内核文件表项(即STRUCT FILE结构),则是采取了共享的方式. 下面代码说明. I值分离 ...

  6. linux 关闭所有文件描述符,close - 关闭一个文件描述符

    SYNOPSIS 总览 #include int close(intfd); DESCRIPTION 描述 close 关闭 一个 文件 描述符 , 使它 不在 指向 任何 文件 和 可以 在 新的 ...

  7. Nginx文件描述符泄露?浅析FD_CLOEXEC文件描述符标志

    很精彩的一篇文章. 1. 引子 事情是这样的,最近我们线上一个基于nginx的http服务经常报警,具体如下: accept() failed (24: Too many open files) wh ...

  8. django为什么需要子进程,如何关闭子进程,linux状态

    django为什么需要子进程 一旦用户用manage.py runserver启动开发服务器,就启动了一个django的进程,当然如果我们用ps aux,这其实是一个Python进程,不过他运行了ma ...

  9. Java 7:在不丢失数据的情况下关闭NIO.2文件通道

    关闭异步文件通道可能非常困难. 如果您将I / O任务提交到异步通道,则需要确保正确执行了任务. 实际上,出于多种原因,这对于异步通道可能是一个棘手的要求. 默认的通道组使用守护进程线程作为工作线程, ...

最新文章

  1. 保护云端数据的5个技巧
  2. 在centos7升级nodejs
  3. gRPC——简介与Hello World
  4. Vue实现Todo List
  5. 03 Oracle分区表
  6. 分类法过时了吗?【ZZ】
  7. python 去除不可见字符\x00
  8. cookie中转注入
  9. JAVA8两个流变量相等_Java8:Stream在同一个流中映射两个属性
  10. 解决postman环境切换,自动获取api签名时间及签名
  11. android 线程安全
  12. plsa java代码_LDA主题聚类学习小结
  13. docker部署aliyundrive-webdav实现阿里云盘WebDAV服务
  14. 文本数据增强(data augmentation)nlpaug使用
  15. c语言输出九九乘法表的实验报告,用C语言输出九九乘法表
  16. JS--统一社会信用代码校验
  17. Swoole vs Workman
  18. 测试iphone4电池的软件,iphone4电池容量 iphone4电池的更换【图文】
  19. Excel插入XactiveX提示出错“不能插入对象”解决
  20. STM32cubemx教程及STM32入门(五)IIC

热门文章

  1. 内外边距、浮动、布局相关
  2. HTML5中的本地数据库-Web SQL Database
  3. 【antd】输入控件的思想
  4. 安装vue-cli时报错
  5. vue 学习之路 —— 图片的引入
  6. CF1080F Katya and Segments Sets
  7. 数据结构(七)排序---直接插入排序(稳定)
  8. javascript 分时函数 分批次添加DOM节点 timeChunk
  9. ReactNative开发环境
  10. webpack基础入门