無論socket,仍是FIFO、管道、終端,對咱們來講,一切都是文件,一切都是流。在信息 交換的過程當中,咱們都是對這些流進行數據的收發操做,簡稱爲I/O操做(input and output),往流中讀出數據,系統調用read,寫入數據,系統調用write。不過話說回來了 ,計算機裏有這麼多的流,我怎麼知道要操做哪一個流呢?對,就是文件描述符,即一般所說的fd,一個fd就是一個整數,因此,對這個整數的操做,就是對這個文件(流)的操做。咱們建立一個socket,經過系統調用會返回一個文件描述符,那麼剩下對socket的操做就會轉化爲對這個描述符的操做。不能不說這又是一種分層和抽象的思想。
同步IO,是一種用戶空間與內核空間的調用發起方式。同步IO是指用戶空間線程是主動發起IO請求的一方,內核空間是被動接受方。
異步IO則反過來,是指內核kernel是主動發起IO請求的一方,用戶線程是被動接受方。
阻塞IO,指的是須要內核IO操做完全完成後,才返回到用戶空間,執行用戶的操做。阻塞指的是用戶空間程序的執行狀態,用戶空間程序需等到IO操做完全完成。傳統的IO模型都是同步阻塞IO。
非阻塞IO,指的是用戶程序不須要等待內核IO操做完成後,內核當即返回給用戶一個狀態值,用戶空間無需等到內核的IO操做完全完成,能夠當即返回用戶空間,執行用戶的操做,處於非阻塞的狀態。
I/O多路複用就經過一種機制,能夠監視多個描述符,一旦某個描述符就緒,可以通知程序進行相應的操做。
select的本質是採用32個整數的32位,即3232= 1024來標識,fd值爲1-1024。當fd的值超過1024限制時,就必須修改FD_SETSIZE的大小。這個時候就能夠標識32max值範圍的fd。
poll與select不一樣,經過一個pollfd數組向內核傳遞須要關注的事件,故沒有描述符個數的限制,pollfd中的events字段和revents分別用於標示關注的事件和發生的事件,故pollfd數組只須要被初始化一次。
epoll仍是poll的一種優化,返回後不須要對全部的fd進行遍歷,在內核中維持了fd的列表。select和poll是將這個內核列表維持在用戶態,而後傳遞到內核中。與poll/select不一樣,epoll再也不是一個單獨的系統調用,而是由epoll_create/epoll_ctl/epoll_wait三個系統調用組成,後面將會看到這樣作的好處。epoll在2.6之後的內核才支持。數組