五種IO模型
1.阻塞I/O模型
老李去火車站買票,排隊三天買到一張退票。
耗費:在車站吃喝拉撒睡 3天,其他事一件沒干。
2.非阻塞I/O模型
老李去火車站買票,隔12小時去火車站問有沒有退票,三天后買到一張票。耗費:往返車站6次,路上6小時,其他時間做了好多事。
3.I/O復用模型
1.select/poll 老李去火車站買票,委托黃牛,然后每隔6小時電話黃牛詢問,黃牛三天內買到票,然后老李去火車站交錢領票。 耗費:打電話 2.epoll 老李去火車站買票,委托黃牛,黃牛買到后即通知老李去領,然后老李去火車站交錢領票。 耗費:無需打電話
4.信號驅動I/O模型
老李去火車站買票,給售票員留下電話,有票后,售票員電話通知老李,然后老李去火車站交錢領票。
耗費:無需打電話
5.異步I/O模型
老李去火車站買票,給售票員留下電話,有票后,售票員電話通知老李並快遞送票上門。
耗費:無需打電話
I/O多路復用
1 它的形成原因
如果一個I/O流進來,我們就開啟一個進程處理這個I/O流。那么假設現在有一百萬個I/O流進來,那我們就需要開啟一百萬個進程一一對應處理這些I/O流(——這就是傳統意義下的
多進程並發處理)。思考一下,一百萬個進程,你的CPU占有率會多高,這個實現方式及其的不合理。所以人們提出了I/O多路復用這個模型,
一個線程,通過記錄I/O流的狀態來同時管理多個I/O,可以提高服務器的吞吐能力
2 它的實現方式 select、poll、epoll
2.1 select函數的調用過程
a. 從用戶空間將fd_set拷貝到內核空間
b. 注冊回調函數
c. 調用其對應的poll方法
d. poll方法會返回一個描述讀寫是否就緒的mask掩碼,根據這個mask掩碼給fd_set賦值。
e. 如果遍歷完所有的fd都沒有返回一個可讀寫的mask掩碼,就會讓select的進程進入休眠模式,直到發現可讀寫的資源后,重新喚醒等待隊列上休眠的進程。如果在規定時間內都沒有喚醒休眠進程,那么進程會被喚醒重新獲得CPU,再去遍歷一次fd。
f. 將fd_set從內核空間拷貝到用戶空間
2.2 select函數優缺點
缺點:兩次拷貝耗時、輪詢所有fd耗時,支持的文件描述符太小
優點:跨平台支持
2.3 poll函數的調用過程(與select完全一致)
2.4 poll函數優缺點
優點:連接數(也就是文件描述符)沒有限制(鏈表存儲)
缺點:大量拷貝,水平觸發(當報告了fd沒有被處理,會重復報告,很耗性能)
2.5 epoll的優點
- 沒有最大並發連接的限制
- 只有活躍可用的fd才會調用callback函數
- 內存拷貝是利用mmap()文件映射內存的方式加速與內核空間的消息傳遞,減少復制開銷。(內核與用戶空間共享一塊內存)
只有存在大量的空閑連接和不活躍的連接的時候,使用epoll的效率才會比select/poll高
3.1 阻塞IO, 給女神發一條短信, 說我來找你了, 然后就默默的一直等着女神下樓, 這個期間除了等待你不會做其他事情, 屬於備胎做法.
3.2 非阻塞IO, 給女神發短信, 如果不回, 接着再發, 一直發到女神下樓, 這個期間你除了發短信等待不會做其他事情, 屬於專一做法.
3.3 IO多路復用, 是找一個宿管大媽來幫你監視下樓的女生, 這個期間你可以些其他的事情. 例如可以順便看看其他妹子,玩玩王者榮耀, 上個廁所等等. IO復用又包括 select, poll, epoll 模式. 那么它們的區別是什么?
3.3.1 select大媽 每一個女生下樓, select大媽都不知道這個是不是你的女神, 她需要一個一個詢問, 並且select大媽能力還有限, 最多一次幫你監視1024個妹子 3.3.2 poll大媽不限制盯着女生的數量, 只要是經過宿舍樓門口的女生, 都會幫你去問是不是你女神 3.3.3 epoll大媽不限制盯着女生的數量, 並且也不需要一個一個去問. 那么如何做呢? epoll大媽會為每個進宿舍樓的女生臉上貼上一個大字條,上面寫上女生自己的名字, 只要女生下樓了, epoll大媽就知道這個是不是你女神了, 然后大媽再通知你.