一文搞懂BIO、NIO、I/O多路復用與異步AIO
1. IO操作本質
4. 數據的復制過程是不消耗CPU的
2. BIO 阻塞模式I/O
舉個例子:
一個人去 商店買一把菜刀,
他到商店問老板有沒有菜刀(發起系統調用)
如果有(表示在內核緩沖區有需要的數據)
老板直接把菜刀給買家(從內核緩沖區拷貝到用戶緩沖區)
這個過程買家一直在等待
如果沒有,商店老板會向工廠下訂單(IO操作,等待數據准備好)
工廠把菜刀運給老板(進入到內核緩沖區)
老板把菜刀給買家(從內核緩沖區拷貝到用戶緩沖區)
這個過程買家一直在等待
是同步io
3. NIO 非阻塞模式I/O
用戶進程發起請求,如果數據沒有准備好,那么立刻告知用戶進程未准備好;此時用戶進程可選擇繼續發起請求、或者先去做其他事情,稍后再回來繼續發請求,直到被告知數據准備完畢,可以開始接收為止; 數據會由用戶進程完成拷貝
舉個例子: 一個人去 商店買一把菜刀, 他到商店問老板有沒有菜刀(發起系統調用) 老板說沒有,在向工廠進貨(返回狀態) 買家去別地方玩了會,又回來問,菜刀到了么(發起系統調用) 老板說還沒有(返回狀態) 買家又去玩了會(不斷輪詢) 最后一次再問,菜刀有了(數據准備好了) 老板把菜刀遞給買家(從內核緩沖區拷貝到用戶緩沖區) 整個過程輪詢+等待:輪詢時沒有等待,可以做其他事,從內核緩沖區拷貝到用戶緩沖區需要等待 是同步io
4. I/O多路復用模型
類似BIO,只不過找了一個代理,來掛起等待,並能同時監聽多個請求; 數據會由用戶進程完成拷貝
舉個例子:多個人去 一個商店買菜刀, 多個人給老板打電話,說我要買菜刀(發起系統調用) 老板把每個人都記錄下來(放到select中) 老板去工廠進貨(IO操作) 有貨了,再挨個通知買到的人,來取刀(通知/返回可讀條件) 買家來到商店等待,老板把到給買家(從內核緩沖區拷貝到用戶緩沖區) 多路復用:老板可以同時接受很多請求(select模型最大1024個,epoll模型), 但是老板把到給買家這個過程,還需要等待, 是同步io
select本質也是輪詢最多可以監聽1024個,而epoll模型是事件驅動,好了會主動告訴你
-select:小明,你寫好了么?小紅你寫好了么?.......
-epoll:同學寫好了,舉手告訴老師來檢查(nginx、tornado用的是epoll)windows平台不支持epoll,用的是select
5. 異步IO-AIO
發起請求立刻得到回復,不用掛起等待; 數據會由內核進程主動完成拷貝,目前不成熟
舉個例子:還是買菜刀
現在是網上下單到商店(系統調用)
商店確認(返回)
商店去進貨(io操作)
商店收到貨把貨發個賣家(從內核緩沖區拷貝到用戶緩沖區)
買家收到貨(指定信號)
整個過程無等待
異步io
- 同步I/O與異步I/O判斷依據是,是否會導致用戶進程阻塞
- BIO中socket直接阻塞等待(用戶進程主動等待,並在拷貝時也等待)
- NIO中將數據從內核空間拷貝到用戶空間時阻塞(用戶進程主動詢問,並在拷貝時等待)
- IO Multiplexing中select等函數為阻塞、拷貝數據時也阻塞(用戶進程主動等待,並在拷貝時也等待)
- AIO中從始至終用戶進程都沒有阻塞(用戶進程是被動的)