【转载】FD_CLOEXEC 的使用

  1. 云栖社区>
  2. 博客列表>
  3. 正文

【转载】FD_CLOEXEC 的使用

摩云飞 2016-05-11 13:36:18 浏览604 评论0

摘要: 通过fcntl设置FD_CLOEXEC标志有什么用?         close on exec, not on-fork, 意为如果对描述符设置了FD_CLOEXEC,使用execl执行的程序里,此描述符被关闭,不能再使用它,但是在使用fork调用的子进程中,此描述符并不关闭,仍可使用。


通过fcntl设置FD_CLOEXEC标志有什么用?  
 

      close on exec, not on-fork, 意为如果对描述符设置了FD_CLOEXEC,使用execl执行的程序里,此描述符被关闭,不能再使用它,但是在使用fork调用的子进程中,此描述符并不关闭,仍可使用。

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

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

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

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

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

1
2
3
4
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了。


【云栖快讯】阿里云栖开发者沙龙(Java技术专场)火热来袭!快来报名参与吧!  详情请点击

网友评论

摩云飞
文章289篇 | 关注25
关注
服务底层使用经国家密码管理局检测认证的硬件密码机,通过虚拟化技术,帮助用户满足数据安全方面的... 查看详情
一种适用于大规模并行批处理作业的分布式云服务。可支持海量作业并发规模,系统自动完成资源管理,... 查看详情
一款安全易用的管理类服务。您无需花费大量成本来保护密钥的保密性、完整性和可用性,借助密钥管理... 查看详情
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效... 查看详情
双12

双12