Linux下一切皆文件豹芯,連外部設(shè)備都當作文件主籍;對文件的讀寫操作會調(diào)用內(nèi)核系統(tǒng)命令,返回文件描述符,簡稱fd览徒;而對socket的讀寫操作也會有描述符挪捕,socketfd萨醒。描述符是一個數(shù)字迁沫,指向內(nèi)核中的結(jié)構(gòu)體(文件路徑、數(shù)據(jù)區(qū))鸳粉。IO操作其實是針對這些內(nèi)核數(shù)據(jù)區(qū)的讀寫扔涧。
阻塞IO
所有的IO操作都是阻塞的,比如recvfrom操作届谈,指到數(shù)據(jù)包到達并且從內(nèi)核數(shù)據(jù)區(qū)拷貝到應(yīng)用數(shù)據(jù)區(qū)或者發(fā)生錯誤才會返回枯夜。期間整個線程會被阻塞。
非阻塞IO
跟阻塞IO相反艰山,所有的IO操作都立即返回湖雹,但是不保證每次都能順利完成IO操作(比如recvfrom操作,如果沒有數(shù)據(jù)可讀程剥,也會立即返回)劝枣,因此需要通過輪詢的方式確保IO操作完成。
IO復(fù)用
不管是上述的阻塞還是非阻塞织鲸,都是針對單描述符來說的,都會導(dǎo)致當前進程/線程的占用(阻塞或者輪詢消耗)溪胶,不能處理其他描述符搂擦。而IO復(fù)用就是解決整個問題出現(xiàn)的,將多個IO的阻塞復(fù)用到同一個select阻塞上哗脖。
select/poll:其實就是維護一個fd列表瀑踢,通過順序掃描的方式來找出就緒的fd并作對應(yīng)的IO操作扳还。select缺陷是fd列表大小有限制,取決于內(nèi)核的FD_SETSIZE,默認是1024橱夭;而且在fd列表很大的情況下氨距,順序掃描的性能也堪憂。
epoll:復(fù)用的原理跟select/poll類似棘劣,但采用了事件驅(qū)動的方式俏让,當fd就緒,則直接調(diào)用對應(yīng)的回調(diào)茬暇。通過這種方式首昔,來取代順序掃描下,fd列表大小的增加導(dǎo)致性能直線下降糙俗;并且epoll的fd數(shù)目是操作系統(tǒng)的最大文件描述符數(shù)勒奇,而不是FD_SETSIZE。
信號驅(qū)動IO
開啟socket信號驅(qū)動IO功能巧骚,通過系統(tǒng)調(diào)用sigaction注冊信號處理函數(shù)赊颠,當IO就緒了,通過信號觸發(fā)信號處理劈彪,通知應(yīng)用程序進行IO操作竣蹦。
異步IO
跟信號驅(qū)動IO類似,不同之處:異步IO是IO操作完成(數(shù)據(jù)拷貝到應(yīng)用數(shù)據(jù)區(qū))之后粉臊,通知應(yīng)用程序草添;而信號驅(qū)動IO還需要應(yīng)用程序去進行IO操作。