系统编程-进程-close-on-exec机制

我的相关博文:

系统编程-进程-exec系列函数超级详解(带各种实操代码)

 

一般我们会调用exec执行另一个程序,此时会用全新的程序替换子进程的正文,数据,堆和栈等。

此时保存文件描述符的变量当然也不存在了,我们就无法关闭无用的文件描述符了。

所以通常的做法是,我们一般会fork子进程后,先在子进程中close那些由于继承得到的,对子进程后续工作无用的文件描述符,再去执行exec装载运行新的程序。

但是在复杂系统中,有时我们fork子进程时已经不知道打开了多少个文件描述符(包括socket句柄等),这此时进行逐一清理确实有很大难度。

我们期望的是能在fork子进程前打开某个文件描述符时就指定好:“这个描述符,我在fork子进程后执行exec时就希望将其关闭”。

其实是有这样的方法解决方案的:即所谓 的 close-on-exec。

以socket为例,我们在父进程中,创建socket的时候,只要加上SOCK_CLOEXEC标志,这样就能够达到我们期望的效果:在fork子进程中执行exec的时候,子进程会自动关闭继承得到的socket。

其他的文件描述符也有类似的功能,例如文件,可以在打开的时候使用O_CLOEXEC标识(linux 2.6.23才开始支持此标记),达到和上面一样的效果。

或者使用系统的fcntl函数设置FD_CLOEXEC也可。

//方案A
int fd     = open(“foo.txt”, O_RDONLY);
int flags  = fcntl(fd,        F_GETFD);
flags     |= FD_CLOEXEC;
fcntl(fd,  F_SETFD,  flags);

//方案B,linux 2.6.23后支持
int fd     = open(“foo.txt”,   O_RDONLY | O_CLOEXEC);

 

 

 

 

.

/************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/13772075.html