針對linux 操做系統的5類IO模型,阻塞式、非阻塞式、多路複用、信號驅動和異步IO進行整理,參考《linux網絡編程》及相關網絡資料。linux
阻塞模式編程
在socket編程(以下圖)中調用以下四類函數致使阻塞:緩存
非阻塞模式服務器
針對上述四類阻塞模式的socket調用,都可經過設置的方式使其非阻塞。設置方式有兩種fcntl設置套接字爲O_NONBLOCK,以及ioctl設置FIONBIO。完成後其四類操做非阻塞,以下:網絡
非阻塞模式在運用中採用輪詢,或配合select的方式使用。異步
多路複用socket
進程定義讀描述符集、寫描述符集以及異常描述符集(做爲select的入參),在select被調用時若是沒有描述符集就緒,該select將被阻塞。當有任何一個或幾個描述符就緒時,select設置描述符集,並返回就緒描述符的個數。函數
/*
* 多路複用select函數,參數定義以下
* nfds: select監視的文件句柄數,通常設置爲最大文件號+1
* readfds:select監視的可讀文件句柄集合
* writefds:select監視的可寫文件句柄集合
* exceptfds:select監視的異常文件句柄集合
*/
int select(nfds, readfds, writefds, exceptfds, timeout)
注:對於監視一個描述符的狀況,select與阻塞模式無區別。spa
信號驅動操作系統
信號驅動的方式屬於一種異步的IO方式,進程自己不會被掛起,流程以下:
信號驅動的IO方式主要分如下三步操做:
signal(SIGIO,sig_handler); //設置SIGIO信號對應的處理函數 fcntl(sockfd,F_SETOWN, getpid());//設置接收SIGIO信號的進程爲當前進程,該信號由sockfd句柄產生 ioctl(sockfd,FIOASYNC,&on);//容許sockfd套接字進行信號驅動的輸入輸出
對於UDP套接字,內核在如下狀況下發送信號SIGIO:
對TCP套接字,內核在如下狀況下發送信號SIGIO:
異步IO
異步IO是linux 2.6內核的標準特性,基本思想是容許進程發起不少IO操做,而不用阻塞或等待任何操做。稍後在接收到IO操做完成的通知時,再檢索IO操做的結果。
aio過程的數據緩存在結構體aiocb中,該結構體定義以下:
struct aiocb { int aio_fildes; /* File desriptor. */ int aio_lio_opcode; /* Operation to be performed. */int aio_reqprio; /* Request priority offset. */ volatile void *aio_buf; /* Location of buffer. */ size_t aio_nbytes; /* Length of transfer. */struct sigevent aio_sigevent; /* Signal number and value. */
根據posix.1b所要求,主要包括以下函數: