使用FD_CLOEXEC实现close-on-exec,关闭子进程无用文件描述符
我們經(jīng)常會碰到需要fork子進(jìn)程的情況,而且子進(jìn)程很可能會繼續(xù)exec新的程序。這就不得不提到子進(jìn)程中無用文件描述符的問題!
fork函數(shù)的使用本不是這里討論的話題,但必須提一下的是:子進(jìn)程以寫時復(fù)制(COW,Copy-On-Write)方式獲得父進(jìn)程的數(shù)據(jù)空間、堆和棧副本,這其中也包括文件描述符。剛剛fork成功時,父子進(jìn)程中相同的文件描述符指向系統(tǒng)文件表中的同一項(這也意味著他們共享同一文件偏移量)。
接著,一般我們會調(diào)用exec執(zhí)行另一個程序,此時會用全新的程序替換子進(jìn)程的正文,數(shù)據(jù),堆和棧等。此時保存文件描述符的變量當(dāng)然也不存在了,我們就無法關(guān)閉無用的文件描述符了。所以通常我們會fork子進(jìn)程后在子進(jìn)程中直接執(zhí)行close關(guān)掉無用的文件描述符,然后再執(zhí)行exec。
但是在復(fù)雜系統(tǒng)中,有時我們fork子進(jìn)程時已經(jīng)不知道打開了多少個文件描述符(包括socket句柄等),這此時進(jìn)行逐一清理確實(shí)有很大難度。我們期望的是能在fork子進(jìn)程前打開某個文件句柄時就指定好:“這個句柄我在fork子進(jìn)程后執(zhí)行exec時就關(guān)閉”。其實(shí)時有這樣的方法的:即所謂的 close-on-exec。
close-on-exec的實(shí)現(xiàn)只需要調(diào)用系統(tǒng)的fcntl就能實(shí)現(xiàn),很簡單幾句代碼就能實(shí)現(xiàn):
int fd=open("foo.txt",O_RDONLY);int flags = fcntl(fd, F_GETFD);flags |= FD_CLOEXEC;fcntl(fd, F_SETFD, flags);這樣,當(dāng)fork子進(jìn)程后,仍然可以使用fd。但執(zhí)行exec后系統(tǒng)就會字段關(guān)閉子進(jìn)程中的fd了。
-------------------------------------------------------- 分割線 ------------------------------------------------------------------------------------
最近好好看了一下open函數(shù),其中flags參數(shù)可以傳入O_CLOEXEC標(biāo)記 [注意:linux 2.6.23才開始支持此標(biāo)記]
這樣就可以一步實(shí)現(xiàn)上面的提到的close-on-exec的效果。
總結(jié)
以上是生活随笔為你收集整理的使用FD_CLOEXEC实现close-on-exec,关闭子进程无用文件描述符的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: srs配置文件分析
- 下一篇: srs rtmp从监听到接收到新连接的过