close
從alloc_fd的實現上看,一般情況下,Linux每次都從上一次分配的fd(利用文件表中的一個變量next_fd記錄),來開始查找未用的文件描述符。這樣保證新分配的文件描述符都是持續增長的,直到上限,然後回繞。

今天我看了close的內核實現,它調用__put_unused_fd用於釋放文件描述符。

static void __put_unused_fd(struct files_struct *files, unsigned int fd)
{
    struct fdtable *fdt = files_fdtable(files);
    __FD_CLR(fd, fdt->open_fds);
    if (fd < files->next_fd)
        files->next_fd = fd;
}
從上面的代碼中,可以發現,當釋放的fd比文件表中的nextfd小的話,nextfd就會更新為當前fd。

結合alloc_fd的代碼,進一步得到Linux文件描述符的選擇策略。當持有的文件描述符關閉時,Linux會盡快的重用該文件描述符,而不是使用遞增的文件描述符值

盡管posix標準沒有說明文件描述符應該如何選擇,但是我並不喜歡當前Linux的策略。當一個正在使用的fd,被另外一個線程關閉時(也許是bug,也許是意外),然後又創建了一個文件描述符。那麽就正好與之前的描述符的值一樣。但是使用之前fd的線程,卻無法察覺到這個變化。結果,如果是普通文件,那麽就可能讀錯或者寫錯文件,如果是socket,那麽就與錯誤的對端進行通信了。

當然,這樣的錯誤可以說是應用層的錯誤。可是作為內核,應該提供好的容錯性。對於fd,如果不迅速重用剛剛關閉的描述符,那麽應用層在使用已關閉文件描述符時,可以立刻返回錯誤。從而避免更嚴重的,並且不易察覺,調試的錯誤。

搞不明白,Linux當前的文件描述符選擇策略有什麽好處?從2.6內核到我目前看到的3.2內核,都是這樣的策略。


Linux文件描述符選擇策略

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 成功运行 的頭像
    成功运行

    成功运行的部落格

    成功运行 發表在 痞客邦 留言(0) 人氣()