"""
我們這裡研究的io模型都是針對網路io的
* blocking io 阻塞io
* nonblocking io 非阻塞io
* io multiplexing io多路復用
* signal driven io 訊號驅動io
* asynchronous io 非同步io
由signal driven io(訊號驅動io)在實際中並不常用,所以主要介紹其餘四種io model。
"""#1)等待資料準備 (waiting for the data to be ready)
#2)將資料從核心拷貝到程序中(copying the data from the kernel to the process)
同步非同步
阻塞非阻塞
常見的網路阻塞狀態:
accept
recv
recvfrom
send雖然它也有io行為 但是不在我們的考慮範圍
io的底層其實是向作業系統要資料,沒有資料則等著
"""
我們之前寫的都是阻塞io模型 協程除外
"""import socket
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while true:
conn, addr = server.accept()
while true:
try:
data = conn.recv(1024)
if len(data) == 0:break
print(data)
conn.send(data.upper())
except connectionreseterror as e:
break
conn.close()
# 在服務端開設多程序或者多執行緒 程序池執行緒池 其實還是沒有解決io問題
該等的地方還是得等 沒有規避
只不過多個人等待的彼此互不干擾
將server.setblocking(false),沒有資料不等且捕獲異常,用for迴圈不斷的check
優點:規避了阻塞
缺點:大量占用cpu
"""
要自己實現乙個非阻塞io模型
"""import socket
import time
server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5)
server.setblocking(false)
# 將所有的網路阻塞變為非阻塞
r_list =
del_list =
while true:
try:
conn, addr = server.accept()
except blockingioerror:
# time.sleep(0.1)
# print('列表的長度:',len(r_list))
# print('做其他事')
for conn in r_list:
try:
data = conn.recv(1024) # 沒有訊息 報錯
if len(data) == 0: # 客戶端斷開鏈結
conn.close() # 關閉conn
# 將無用的conn從r_list刪除
continue
conn.send(data.upper())
except blockingioerror:
continue
except connectionreseterror:
conn.close()
# 揮手無用的鏈結
for conn in del_list:
r_list.remove(conn)
del_list.clear()
# 客戶端
import socket
client = socket.socket()
client.connect(('127.0.0.1',8081))
while true:
client.send(b'hello world')
data = client.recv(1024)
print(data)
用select模組把不斷的check的操作交給作業系統來做,
"""
當監管的物件只有乙個的時候 其實io多路復用連阻塞io都比比不上!!!
但是io多路復用可以一次性監管很多個物件
server = socket.socket()
conn,addr = server.accept()
監管機制是作業系統本身就有的 如果你想要用該監管機制(select)
需要你匯入對應的select模組
"""import socket
import select
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
server.setblocking(false)
read_list = [server]
while true:
r_list, w_list, x_list = select.select(read_list, , )
"""幫你監管
一旦有人來了 立刻給你返回對應的監管物件
"""# print(res) # (, , )
# print(server)
# print(r_list)
for i in r_list: #
"""針對不同的物件做不同的處理"""
if i is server:
conn, addr = i.accept()
# 也應該新增到監管的佇列中
else:
res = i.recv(1024)
if len(res) == 0:
i.close()
# 將無效的監管物件 移除
read_list.remove(i)
continue
print(res)
i.send(b'heiheiheiheihei')
# 客戶端
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
while true:
client.send(b'hello world')
data = client.recv(1024)
print(data)
總結
"""
監管機制其實有很多
select機制 windows linux都有
poll機制 只在linux有 poll和select都可以監管多個物件 但是poll監管的數量更多
上述select和poll機制其實都不是很完美 當監管的物件特別多的時候
可能會出現 極其大的延時響應
epoll機制 只在linux有
它給每乙個監管物件都繫結乙個**機制
一旦有響應 **機制立刻發起提醒
針對不同的作業系統還需要考慮不同檢測機制 書寫**太多繁瑣
有乙個人能夠根據你跑的平台的不同自動幫你選擇對應的監管機制
selectors模組
"""
任務提交了之後程式做其他的事,當任務有結果時,會觸發**機制,轉而回來處理該資料
"""
非同步io模型是所有模型中效率最高的 也是使用最廣泛的
相關的模組和框架
模組:asyncio模組
非同步框架:sanic tronado twisted
速度快!!!
"""import threading
import asyncio
@asyncio.coroutine
def hello():
print('hello world %s'%threading.current_thread())
yield from asyncio.sleep(1) # 換成真正的io操作
print('hello world %s' % threading.current_thread())
loop = asyncio.get_event_loop()
tasks = [hello(),hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
網路程式設計之IO模型
io多路復用概念 io發生時涉及的物件和步驟。對於乙個網路io,它會涉及到兩個系統物件,乙個是呼叫io的程序或者執行緒,另乙個就是系統核心。如當乙個read操作發生時,會先等待資料準備,然後將資料從核心拷貝到程序中去 阻塞io blocking io 特點 在執行io的兩個階段 等待資料和拷貝資料兩...
網路程式設計之IO模型 非同步IO
linux下的asynchronous io其實用得不多,從核心2.6版本才開始引入。先看一下它的流程 使用者程序發起read操作之後,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當它受到乙個asynchronous read之後,首先它會立刻返回,所以不會對使用者程序產生任何bl...
Linux網路程式設計之IO模型
同步是指乙個任務的完成需要依賴另外乙個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成。非同步是指不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工作,依賴的任務也立即執行,只要自己完成了整個任務就算完成了,非同步一般使用狀態 通知和 阻塞是指呼叫結果返回之前,當前執行緒會被掛起,...