非阻塞IO模型 nonblocking IO
阿新 • • 發佈:2018-11-14
非阻塞IO模型
非阻塞IO模型的就是將原來的阻塞操作變成非阻塞的,當原來阻塞操作程式設計操作後就會有訊號,沒有訊號的就就幹其他事情,迴圈詢問,迴圈執行其他事情,直到作業系統返回正確的訊號就會繼續執行。
import socket server = socket.socket() #重用埠 server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) server.bind(("127.0.0.1",5555)) server.listen(5) #將原來的阻塞(像是accept等)程式設計非阻塞server.setblocking(False) #存在的連線列表 clients = [] data_dic = [] while True: try: conn,addr = server.accept() #只有接到連線才是正常執行 #丟擲異常相當於,作業系統告訴應用程式,阻塞需要的訊息不存在,去執行其他任務 clients.append(conn)#將連線儲存,然後集體操作連線 except BlockingIOError: #沒有連線建立丟擲異常 #轉其他工作,像是接受已經建立連線的資訊for c in clients[:]: try: data = c.recv(1024)#非阻塞 if not data: c.close()#關閉連線 # 將不存在的客戶端連線刪除,取消下次的無用操作 clients.remove(c) continue#linux 的錯誤連線 #接受資料將資料和連線放進字典data_dic.append((c,data.upper())) except BlockingIOError: #沒有接到傳送的資料 pass except ConnectionResetError: #關閉連線 clients.remove(c) c.close() #其他任務之傳送資訊給客戶端(當無法繼續接受資訊後) for data in data_dic[:]: try: data[0].send(data[1]) #傳送刪除,防止下次繼續發 data_dic.remove(data) except BlockingIOError: continue except ConnectionResetError: # 客戶端連線需要刪除 data[0].close()#關閉連線 clients.remove(data[0])#移除連線 data_dic.remove(data)#移除傳送資訊
這裡將異常作為accept和recv等wait data 的阻塞,將異常作為訊號,接到訊號處理其他任務的非阻塞解決方案。