Linux很重要的設(shè)計(jì)思想就是一切皆文件,網(wǎng)絡(luò)是文件,鍵盤(pán)等外設(shè)也是文件,很神奇吧?于是所有資源都有了統(tǒng)一的接口,開(kāi)發(fā)者可以像寫(xiě)文件那樣通過(guò)網(wǎng)絡(luò)傳輸數(shù)據(jù),我們也可以通過(guò)/proc/
的文件看到進(jìn)程的資源使用情況。
內(nèi)核給每個(gè)訪問(wèn)的文件分配了文件描述符(File Descriptor),它本質(zhì)是一個(gè)非負(fù)整數(shù),在打開(kāi)或新建文件時(shí)返回,以后讀寫(xiě)文件都要通過(guò)這個(gè)文件描述符了。
我們想想操作系統(tǒng)打開(kāi)的文件這么多,不可能他們共用一套文件描述符整數(shù)吧?這樣想就對(duì)了,Linux實(shí)現(xiàn)時(shí)這個(gè)fd其實(shí)是一個(gè)索引值,指向每個(gè)進(jìn)程打開(kāi)文件的記錄表。
POSIX已經(jīng)定義了STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO三個(gè)常量,也就是0、1、2。這三個(gè)文件描述符是每個(gè)進(jìn)程都有的,這也解釋了為什么每個(gè)進(jìn)程都有編號(hào)為0、1、2的文件而不會(huì)與其他進(jìn)程沖突。
文件描述符幫助應(yīng)用找到這個(gè)文件,而文件的打開(kāi)模式等上下文信息存儲(chǔ)在文件對(duì)象中,這個(gè)對(duì)象直接與文件描述符關(guān)聯(lián)。
注意了,每個(gè)系統(tǒng)對(duì)文件描述符個(gè)數(shù)都有限制。我們網(wǎng)上看到配置ulimit
也是為了調(diào)整系統(tǒng)的打開(kāi)文件個(gè)數(shù),因?yàn)橐话惴?wù)器都要同時(shí)處理成千上萬(wàn)個(gè)起請(qǐng)求,記住socket連接也是文件哦,使用系統(tǒng)默認(rèn)值會(huì)出現(xiàn)莫名奇怪的問(wèn)題。
講文件描述符其實(shí)是為高深莫測(cè)的epoll做鋪墊,掌握epoll對(duì)進(jìn)程已經(jīng)有很深的理解了。