網路IO模型

2022-08-23 07:00:13 字數 3829 閱讀 2791

一、阻塞io模型

阻塞io基於socket程式

原理:

① recv接收資料時,不是直接接收資料,而是程式將系統呼叫的命令傳送到作業系統

② 當作業系統收到接收資料的請求,若此時無資料,作業系統會繼續等待,處於等待資料階段(wait for data階段),這個階段相對漫長

③ 當資料來了,作業系統會拷貝資料(copy data 階段),從核心copy到記憶體

④ 當作業系統copy結束後,程式就能獲取到recv的資料

阻塞io模型都會經歷兩個階段

wait for data 階段    阻塞

copy data 階段                   阻塞

存在的問題:一旦阻塞不能執行其他的任務 

二、非阻塞io模型

特點:① 選擇性阻塞,可以執行其他任務

② 沒有併發程式設計的機制,是乙個同步的程式

③ 由於非阻塞的特點,程式不會在某乙個連線recv或者sk.accept上進行阻塞,由更多的時間來做資訊的收發,用一條執行緒實現併發的效果

① 程式發起recv,進行系統呼叫

② 作業系統接收命令後,若此時無資料,作業系統會返回到程式

③ 當有資料時,作業系統從核心copy到記憶體裡

④ 拷貝結束後,程式會接收到資料

缺點:高速執行,占用太多的cpu導致資源浪費,給cpu造成了很大的負擔

程式模擬

#

非阻塞io模型

import

socket

sk =socket.socket()

sk.bind((

'127.0.0.1

',9000))

sk.setblocking(false)

#設定socket server為非阻塞

sk.listen()

conn_lis = #

鏈結的列表

del_lis = #

斷開鏈結的列表

while 1:

try:

conn,addr =sk.accept()

except

blockingioerror:

for conn in

conn_lis:

try:

conn.send(b

'hello

')

print(conn.recv(1024))

except (nameerror,blockingioerror):pass

except connectionreseterror: #

客戶端埠連線後

conn.close() #

關閉鏈結

新增到斷開鏈結的列表

for del_conn in del_lis: #

從鏈結列表裡刪除斷開的鏈結

conn_lis.remove(del_conn)

del_lis.clear()

#清空斷開鏈結的列表

三、io多路復用模型原理:非阻塞的情況下加上**

**是io多路復用機制提供的**,作業系統提供io多路復用的機制,提供了乙個模組select

select 沒模組用來作業系統中的select(io多路復用)機制

select.select(rlist,wlist,xlist)    # 按位置傳參,傳入列表

rlist       讀

wlist      寫

xlist       特殊的條件

① 程式有乙個**(代替conn),**進行系統呼叫,向作業系統發出命令,詢問是否有資料

② 此時作業系統沒資料,作業系統一直等待資料,**會一直阻塞

③ 當有資料來了,資料準備好了,通知被**的物件,conn收到資訊,conn發起recv

④ 此作業系統copy資料,作業系統進入copy資料階段

⑤ copy完成,recv拿到資料

程式

import

select

import

socket

sk =socket.socket()

sk.bind((

'127.0.0.1

',9000))

sk.setblocking(false)

sk.listen()

r_lis = [sk] #

存的是socket物件

while 1:

r_l,_,_ = select.select(r_lis,,) #

按位置引數,不需要的引數要傳入空列表

for item in

r_l:

if item is sk: #

判斷是否有鏈結

conn,addr =sk.accept()

else

:

try:

print((item.recv(1024)).decode()) #

conn有訊息接收

item.send(b'

hello')

except connectionreseterror: #

客戶端斷開鏈結

item.close() #

關閉鏈結conn

r_lis.remove(item)

io多路復用是作業系統的工具,模組 select、poll、epoll都是發揮**的作用,進行監聽。但在windows上只有select模組,而在mac/linux系統上,三種機制並存。

select的底層是作業系統在做輪詢,有監聽物件個數的限制,並且隨著監聽物件的個數越來越多,效率越來越低

poll 跟 select 一樣,但監聽的個數比 select 要多

epoll 給每乙個要監聽的物件都繫結了乙個**函式,資料來了直接呼叫物件,不再受到個數增加而降低效率的影響

sockserver 底層使用了io多路復用 + threading執行緒實現的

selectors模組,在不同的系統上進行io多路復用機制的自動篩選

io多路復用的好處:多個conn使用乙個**,整體的程式顯得不忙碌,既能實現併發,又能節省資源

四、非同步io模型

不需要做任何操作,直接發指令即可

過程:程式發起資訊,作業系統立即給反應,作業系統一直在監聽,當資料來了,會直接將資料放到記憶體中去,程式可以直接去記憶體讀取

但是python暫時沒有對應的模組去使用非同步io

等待資料階段和拷貝資料階段都不需要使用者處理

所有的操作都由作業系統替你完成

copy資料階段,只有非同步io是不需要阻塞的

網路IO模型

為了更好地了解io模型,我們需要事先回顧下 同步 非同步 阻塞 非阻塞 1.網路傳輸中的兩個階段 分別是 waitdata 和 copydata send copydata recv waitdata copydata 記住這兩點很重要,因為這些io模型的區別就是在兩個階段上各有不同的情況。2.阻塞...

網路IO模型

io有兩種操作,同步io和非同步io。同步io指的是,必須等待io操作完成後,控制權才返回給使用者程序。非同步io指的是,無須等待io操作完成,就將控制權返回給使用者程序。網路中的io,由於不同的io裝置有著不同的特點,網路通訊中往往需要等待。常見的有以下4種情況。1 輸入操作 等待資料到達套接字接...

網路I O模型 5種常見的網路I O模型

阻塞與非阻塞 阻塞就是卡在那兒什麼也不做,雙方之間也沒有資訊溝通。非阻塞就是即使對方不能馬上完成請求,雙方之間也有資訊的溝通。同步與非同步 同步就是一件事件只由乙個過程處理完成,不論阻塞與非阻塞,最後完成這個事情的都是同乙個過程 非同步就是一件事由兩個過程完成,前面乙個過程通知,後面乙個過程接受返回...