異步io和協程
阿新 • • 發佈:2018-02-24
error cep 實現 tornado www. append end pre exceptio
常見的異步io模塊asyncio、gevent、twisted、tornado
核心技術為select()和協程
異步io請求的本質則是【非阻塞Socket】+【IO多路復用】
協程在這裏不是一個必須使用的技術,在使用select()事件驅動循環本身就可以達到單線程異步的效果
io協程在遇到阻塞時進行切換,其實現需要依賴select()事件循環進行切換
協程本質是一種上下文切換技術,通過生成器yield記錄狀態的特性來實現
r,w,e = select.select([rlist],[wlist],[error],timeout)
select:采用事件輪詢方式,即在while True下不斷輪詢所有的socket,
某個socket有數據返回時通知用戶進程,最大輪詢事件為1024,可以跨平臺,水平觸發
poll:方式相同,沒有最大輪詢事件數量限制
epoll:方式不同,比如100個連接,有兩個活躍了,epoll會告訴用戶這兩個兩個活躍了,直接取就ok了,而select是循環一遍。
select/epoll的優勢並不是對於單個連接能處理得更快,而是在於能處理更多的連接。
如果處理的連接數不是很高的話,使用select/epoll的web server不一定比使用multi-threading + blocking IO
的web server性能更好,可能延遲還更大。
1 import socket,select 2 3 socket_list = [ 4 (‘www.baidu.com‘,80), 5 (‘202.89.233.100‘,80), 6 (‘101.37.225.65‘,80), 7 ] 8 soc_list = [] 9 conn_list=[]異步io客戶端10 for s in socket_list: 11 c = socket.socket() 12 c.setblocking(False) 13 try: 14 c.connect(s) 15 except Exception as e: 16 pass 17 soc_list.append(c) 18 conn_list.append(c) 19 print(soc_list) 20 while True: 21 r,w,error = select.select(soc_list,conn_list,[])22 for i in soc_list: 23 try: 24 while True: 25 data = i.sock.recv(8096) 26 print(i) 27 if not data: 28 soc_list.remove(i) 29 except Exception as e: 30 pass 31 32 for i in conn_list: 33 i.sendall("""GET /index HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n""") 34 conn_list.remove(i)
異步io和協程