一、IO模型介紹
1、阻塞與非阻塞指的是程序的兩種運行狀態
阻塞:遇到IO就發生阻塞,程序一旦遇到阻塞操作就會停在原地,并且立刻釋放CPU資源
非阻塞(就緒態或運行態):沒有遇到IO操作,或者通過某種手段讓程序即便是遇到IO操作也不會停在原地,執行其他操作,力求盡可能多的占有CPU
2、同步與異步指的是提交任務的兩種方式:
同步調用:提交完任務后,就在原地等待,直到任務運行完畢后,拿到任務的返回值,才繼續執行下一行代碼
異步調用:當進程執行到一個IO(等待外部數據)的時候,不需要等待,待數據接收成功后,再回來處理。
?
1.io模型 提交任務得方式:同步:提交完任務,等結果,執行下一個任務異步:提交完,接著執行,異步 + 回調 異步不等結果,提交完任務,任務執行完后,會自動觸發回調函數 同步不等于阻塞:阻塞:遇到io,自己不處理,os會搶走cpu ,解決辦法:監測到io,gevent切換到其他任務,類似欺騙os非阻塞:cpu 運行 IO分類:1.阻塞IO blocking IO2.非阻塞IO nonblocking IO3.IO多路復用 IO multiplexing4.信號驅動IO signal driven IO 用得比較少 5.異步IO asynchronous IO 遇到IO: 卡網絡IO: 原地阻塞1.server端什么樣得操作屬于IO行為 # accept recv send 阻塞操作 accept recv 明顯得等 send 不會明顯等,但是一種io行為 2.為什么IO行為會讓有在原地等待的效果 3.非阻塞io: 自己監測io 遇到io 就切 并且把 單線程得效率提到最高 導致得問題:1.當有數據來得時候,cpu 在做其他得事情,不會立即響應2.服務端沒有任何阻塞,說白了,就是死循環,cpu會一直運轉,線程處于就緒狀態,大量占用cpu ,做無用,這個線程會一直問cpu,有數據沒,有數據沒 不推薦使用4.多路復用io:wait copy 還多了select 中間有個中介存在,幫問os 有沒有數據但是如果中介 只有1個 效率不如 阻塞效率但是如果中介監測多個套接字 ,性能高就是:同時監測多個套接字問os系統好了沒 就比阻塞io效率高監測套接字得io行為服務端得套接字有幾類:server connselect 阻塞io 效率高比非阻塞io 效率也高 ,一直做無用總結:同時監測多個套接字列表 循環 慢 假設列表數據多,循環 效率低 監測套接字好沒好 從頭到尾 循環1遍select 列表循環 效率低poll 可接收得列表數據多 效率也不高epoll 效率最高得 異步操作 每個套接字身上綁定個回調函數,誰好了誰觸發回調,(就不用去遍歷了 效率低)epoll windows 不支持linux 支持selectors 模塊 自動根據操作系統選擇pollepoll
?
二、阻塞IO模型
默認情況下,所有的socket都是blocking模型,
實際上,除非特別指定,幾乎所有的IO接口 ( 包括socket接口 ) 都是阻塞型的。
這給網絡編程帶來了一個很大的問題,如在調用recv(1024)的同時,線程將被阻塞,在此期間,線程將無法執行任何運算或響應任何的網絡請求。
blocking IO的特點就是在IO執行的兩個階段(等待數據和拷貝數據兩個階段)都被block了。
?
?
?
?
三、非阻塞IO模型
?
在非阻塞式IO中,用戶進程其實是需要不斷的主動詢問kernel數據準備好了沒有。


from socket import *server = socket(AF_INET, SOCK_STREAM) server.bind(('127.0.0.1',8083)) server.listen(5) server.setblocking(False) print('starting...')rlist=[] wlist=[] while True:try:conn, addr = server.accept()rlist.append(conn)print(rlist)except BlockingIOError:# print('干其他的活')#收消息del_rlist = []for conn in rlist:try:data=conn.recv(1024)if not data:del_rlist.append(conn)continuewlist.append((conn,data.upper()))except BlockingIOError:continueexcept Exception:conn.close()del_rlist.append(conn)#發消息del_wlist=[]for item in wlist:try:conn=item[0]data=item[1]conn.send(data)del_wlist.append(item)except BlockingIOError:passfor item in del_wlist:wlist.remove(item)for conn in del_rlist:rlist.remove(conn)server.close()
四、多路復用IO模型
?
五、異步IO模型
六、各種IO模型對比
七、了解selectors模塊的使用
?