close-on-exec机制

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

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

因此一般的作法是,咱们通常会fork子进程后,先在子进程中close那些因为继承获得的,对子进程后续工做无用的文件描述符,再去执行exec装载运行新的程序。函数

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

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

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

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

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

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

//方案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);

 

 

 

 

 

 

 

 

.变量

相关文章
相关标签/搜索