通常咱們會調用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);
.變量