5種I/O模型:
1.阻塞I/O
2.非阻塞I/O
3.異步I/O
4.信號驅動I/O
5.I/O復用
信號驅動和異步驅動的區別
信號驅動IO是指:進程預先告知內核,使得 當某個socketfd有events(事件)發生時,內核使用信號通知相關進程。
異步IO(Asynchronous IO)是指:進程執行IO系統調用(read / write)告知內核啟動某個IO操作,內核啟動IO操作后立即返回到進程。IO操作即內核當中的服務例程。
異步I/O和信號驅動I/O的區別很容易被混淆。前者與后者的區別在於啟用異步I/O意味着通知內核啟動某個I/O操作,並讓內核在整個操作(包括數據從內核復制到用戶緩沖區)完成時通知我們。也就是說,異步I/O是由內核通知我們I/O操作何時完成,即實際的I/O操作也是異步的;而 信號驅動I/O是由內核通知我們何時可以啟動一個I/O。
I/O究竟什么時候能用這個信息實際上只有內核才能 事先知道,因為是內核在最終處理系統中的所有打開的描述符。
信號驅動I/O模型
內核:I/O能用了。
進程:接受到I/O能用的消息並執行接下來的操作。
異步I/O模型
內核:等待這個I/O有消息了,接受到數據。
進程:從緩存中得到數據。
信號驅動的作用在於在等待I/O可用的過程中可以執行其它的指令,這種方法從理論上看 倒是不錯。由於進程已經休眠,就不會再占用CPU,僅當I/O可用時它才恢復執行。但是這種方法的問題在於信號處理的開銷有點大。若只是少數的請求還沒有問題,若是每分鍾收到100個請求,那就幾乎一直都在捕獲信號。每秒鍾捕獲上百個信號的開銷是相當大的,不單是進程,對於內核發送信號的開銷而言也是一樣的。
因此,在高性能的服務器編程中,用異步I/O來處理多個I/O更為高效。當然,也可以用I/O復用模型來實現(epoll是一個相當高效的方法),但是對於Regular File來說,是不能使用epoll的,因為不能設置非阻塞模式(O_NOBLOCK 方式對於傳統文件句柄是無效的),這個時候,異步I/O是一個很不錯的選擇。