1. 程式人生 > >異步io和協程

異步io和協程

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=[]
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客戶端

異步io和協程