通常咱们会调用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);
.变量