天天看點

Linux網絡程式設計 | IO模型 :阻塞IO、非阻塞IO、信号驅動IO、異步IO、多路複用IOIO模型阻塞IO非阻塞IO信号驅動IO多路複用IO異步IO

目錄

  • IO模型
    • 阻塞與非阻塞
    • 同步與異步
  • 阻塞IO
  • 非阻塞IO
  • 信号驅動IO
  • 多路複用IO
  • 異步IO

IO模型

根據各自的特性不同,IO模型被分為阻塞IO、非阻塞IO、信号驅動IO、異步IO、多路複用IO五類。

最主要的兩個差別就是阻塞與非阻塞,同步與異步。

阻塞與非阻塞

阻塞與非阻塞最主要的差別就是程式在等待調用結果時的狀态。

阻塞:為了完成一個功能發起調用,如果不具備完成功能的條件,則調用會一直等待

非阻塞:為了完成一個功能發起調用,如果不具備完成功能的條件,則立即報錯傳回

同步與異步

同步與異步最主要的差別就是功能完成的流程是否是順序化的,且完成的是自身還是系統。

同步:功能完成的流程是順序化的,并且功能由自身完成。

異步:功能完成的流程是不确定的,并且功能由系統完成。

阻塞IO

發起IO調用,如果不具備IO條件,則一直等待直到條件就緒。

Linux網絡程式設計 | IO模型 :阻塞IO、非阻塞IO、信号驅動IO、異步IO、多路複用IOIO模型阻塞IO非阻塞IO信号驅動IO多路複用IO異步IO

優點:流程以及代碼實作都非常簡單,任務順序操作。

缺點:任務處理效率較低,無法充分利用資源。

非阻塞IO

發起一個IO調用,如果不具備IO條件,則立即報錯傳回,繼續執行其他指令。通過一個循環來不斷發起IO請求,直到條件就緒。

Linux網絡程式設計 | IO模型 :阻塞IO、非阻塞IO、信号驅動IO、異步IO、多路複用IOIO模型阻塞IO非阻塞IO信号驅動IO多路複用IO異步IO

優點:與阻塞IO相比較來說,利用了等待的時間去做了其他的事情,對資源的利用更加充分。

缺點:與阻塞IO對比,IO調用需要循環發起,流程更加複雜。并且如果IO條件就緒了,也要等待上一輪循環結束後進入目前循環,才能進行處理,這就導緻了IO不夠實時。

非阻塞IO可以通過fcntl函數設定描述符狀态來實作

例如:

void SetNoBlock(int fd) 
{
	int flag = fcntl(fd, F_GETFL, 0);
	
	flag |= O_NONBLOCK;
	fcntl(fd, F_SETFL, flag);
}
           

信号驅動IO

自定義一個IO就緒的信号,當IO就緒時就發出這個信号。在沒有收到信号時,可以繼續處理其他事情,一旦收到信号,就會中斷目前操作,來優先處理IO事件。

Linux網絡程式設計 | IO模型 :阻塞IO、非阻塞IO、信号驅動IO、異步IO、多路複用IOIO模型阻塞IO非阻塞IO信号驅動IO多路複用IO異步IO

優點:相較于非阻塞IO,因為信号到來後就直接強行中斷進行處理,更加實時。并且在沒收到信号的時候可以執行其他工作,資源利用更加充分。

缺點:因為需要自定義信号,又要有主要流程也要有信号處理流程,并且還需要考慮信号是否可靠導緻的事件丢失情況,流程會更加的複雜。

多路複用IO

用于對大量的IO事件進行監控,能夠讓使用者隻針對就緒了指定事件(可讀、可寫、異常) 的IO進行IO操作。隻針對就緒的描述符進行操作,避免了阻塞,并且提高了效率。

在Linux下,作業系統提供了三種模型:select模型、poll模型、epoll模型。這三種模型的具體使用以及細節會放到下一篇部落格中

Linux網絡程式設計 | IO模型 :阻塞IO、非阻塞IO、信号驅動IO、異步IO、多路複用IOIO模型阻塞IO非阻塞IO信号驅動IO多路複用IO異步IO

根據不同的模型具體的優缺點也不一樣。

異步IO

IO處理的順序不确定,整個IO的過程(等待 + 資料拷貝)由作業系統來完成而并非使用者。

Linux網絡程式設計 | IO模型 :阻塞IO、非阻塞IO、信号驅動IO、異步IO、多路複用IOIO模型阻塞IO非阻塞IO信号驅動IO多路複用IO異步IO

流程:

  1. 自定義一個IO完成信号
  2. 發起異步調用後傳回,此時使用者可以繼續處理其他事情
  3. 系統進行IO事件的等待以及資料拷貝
  4. IO完成後通過信号通知程序IO

優點:對資源的利用最為充分, 以最高的效率進行任務的處理

缺點:資源消耗較高, 流程最為複雜

上面的五種IO模型,從前往後處理的效率逐漸增加,對資源的利用也增加充分,但是流程也越來越複雜。

繼續閱讀