進程與線程的描述
一個進程至少會創建一個線程,多個線程共享一個程序進程的內存。程序的運行最終是靠線程來完成操作的。線程的數量跟CPU核數有關,一個核最多能發出兩個線程。線程的操作主要分為:一:給CPU進行程序命令的執行。二:IO的操作(讀取或輸出數據)或者請求網絡數據。
IO復用形成原因
如果一個I/O流進來,我們就開啟一個進程處理這個I/O流。那么假設現在有一百萬個I/O流進來,那我們就需要開啟一百萬個進程一一對應處理這些I/O流(——這就是傳統意義下的多進程並發處理)。思考一下,一百萬個進程,你的CPU占有率會多高,這個實現方式及其的不合理。所以人們提出了I/O多路復用這個模型,一個線程,通過記錄I/O流的狀態來同時管理多個I/O,可以提高服務器的吞吐能力
IO模型
阻塞IO模型

非阻塞IO模型

IO復用模型

信號驅動式IO模型

異步IO模型

多路復用的實現有多種方式:select、poll、epoll
select
調用過程
a. 從用戶空間將fd_set拷貝到內核空間
b. 注冊回調函數
c. 調用其對應的poll方法
d. poll方法會返回一個描述讀寫是否就緒的mask掩碼,根據這個mask掩碼給fd_set賦值。
e. 如果遍歷完所有的fd都沒有返回一個可讀寫的mask掩碼,就會讓select的進程進入休眠模式,直到發現可讀寫的資源后,重新喚醒等待隊列上休眠的進程。如果在規定時間內都沒有喚醒休眠進程,那么進程會被喚醒重新獲得CPU,再去遍歷一次fd。
f. 將fd_set從內核空間拷貝到用戶空間
優缺點
缺點:兩次拷貝耗時、輪詢所有fd耗時,支持的文件描述符太小
優點:跨平台支持
poll
調用過程(與select完全一致)
優缺點
優點:連接數(也就是文件描述符)沒有限制(鏈表存儲)
缺點:大量拷貝,水平觸發(當報告了fd沒有被處理,會重復報告,很耗性能)
epoll
epoll的ET與LT模式
LT:延遲處理,當檢測到描述符事件通知應用程序,應用程序不立即處理該事件。那么下次會再次通知應用程序此事件。
ET:立即處理,當檢測到描述符事件通知應用程序,應用程序會立即處理。
ET模式減少了epoll被重復觸發的次數,效率比LT高。我們在使用ET的時候,必須采用非阻塞套接口,避免某文件句柄在阻塞讀或阻塞寫的時候將其他文件描述符的任務餓死
調用過程
a. 當調用epoll_wait函數的時候,系統會創建一個epoll對象,每個對象有一個evenpoll類型的結構體與之對應,結構體成員結構如下。
rbn,代表將要通過epoll_ctl向epll對象中添加的事件。這些事情都是掛載在紅黑樹中。
rdlist,里面存放的是將要發生的事件
b. 文件的fd狀態發生改變,就會觸發fd上的回調函數
c. 回調函數將相應的fd加入到rdlist,導致rdlist不空,進程被喚醒,epoll_wait繼續執行。
d. 有一個事件轉移函數——ep_events_transfer,它會將rdlist的數據拷貝到txlist上,並將rdlist的數據清空。
e. ep_send_events函數,它掃描txlist的每個數據,調用關聯fd對應的poll方法去取fd中較新的事件,將取得的事件和對應的fd發送到用戶空間。如果fd是LT模式的話,會被txlist的該數據重新放回rdlist,等待下一次繼續觸發調用。
優缺點
優點:
- 沒有最大並發連接的限制
- 只有活躍可用的fd才會調用callback函數
- 內存拷貝是利用mmap()文件映射內存的方式加速與內核空間的消息傳遞,減少復制開銷。(內核與用戶空間共享一塊內存)
只有存在大量的空閑連接和不活躍的連接的時候,使用epoll的效率才會比select/poll高
總結
IO分兩階段:
1.數據准備階段 2.內核空間復制回用戶進程緩沖區階段
一般來講:阻塞IO模型、非阻塞IO模型、IO復用模型(select/poll/epoll)、信號驅動IO模型都屬於同步IO,因為階段2是阻塞的(盡管時間很短)。只有異步IO模型是符合POSIX異步IO操作含義的,不管在階段1還是階段2都可以干別的事。
