該篇的IO模型主要針對的是網路IO的,其他IO不在本篇考慮範圍之內! IO模型簡介 Stevens在文章中一共比較了五種IO Model,分別為: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路復用 * signal ...
該篇的IO模型主要針對的是網路IO的,其他IO不在本篇考慮範圍之內!
IO模型簡介
Stevens在文章中一共比較了五種IO Model,分別為:
* blocking IO 阻塞IO
* nonblocking IO 非阻塞IO
* IO multiplexing IO多路復用
* signal driven IO 信號驅動IO
* asynchronous IO 非同步IO
由signal driven IO(信號驅動IO)在實際中並不常用,所以主要介紹其餘四種IO Model。
我們常見的io操作有:
同步非同步
阻塞非阻塞
常見的網路阻塞狀態:
accept
recv
recvfrom
send雖然它也有io行為 但是不在我們的考慮範圍
IO傳輸數據時的圖解
1)等待數據準備 (Waiting for the data to be ready)
2)將數據從內核拷貝到進程中(Copying the data from the kernel to the process)
阻塞IO模型
我們之前寫的都是阻塞IO模型 協程除外
# 在服務端開設多進程或者多線程 進程池線程池 其實還是沒有解決IO問題
該等的地方還是得等 沒有規避
只不過多個人等待的彼此互不幹擾
非阻塞IO模型
雖然非阻塞IO給你的感覺非常的牛逼
但是該模型會 長時間占用著CPU並且不幹活 讓CPU不停的空轉
我們實際應用中也不會考慮使用非阻塞IO模型
IO多路復用
"""
當監管的對象只有一個的時候 其實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) # ([<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)>], [], [])
# print(server)
# print(r_list)
for i in r_list: #
"""針對不同的對象做不同的處理"""
if i is server:
conn, addr = i.accept()
# 也應該添加到監管的隊列中
read_list.append(conn)
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模塊
"""