多路复用IO和异步IO
多路復用I/O
它的基本原理就是select/epoll這個function會不斷的輪詢所負責的所有socket,當某個socket有數據到達了,就通知用戶進程。
流程圖如下:
?
當用戶進程調用了select,那么整個進程會被block,而同時,kernel會“監視”所有select負責的socket,當任何一個socket中的數據準備好了,select就會返回。這個時候用戶進程再調用read操作,將數據從kernel拷貝到用戶進程。
強調
1. 如果處理的連接數不是很高的話,使用select/epoll的web server不一定比使用multi-threading blocking IO的web server性能更好,可能延遲還更大。select/epoll的優勢并不是對于單個連接能處理得更快,而是在于能處理更多的連接。
? ? 2.?在多路復用模型中,對于每一個socket,一般都設置成為non-blocking,但是,如上圖所示,整個用戶的process其實是一直被block的。只不過process是被select這個函數block,而不是被socket IO給block。
? ??結論: select的優勢在于可以處理多個連接,不適用于單個連接??
?
1 from socket import * 2 import time 3 import select 4 5 6 server = socket(AF_INET, SOCK_STREAM) 7 server.bind(('127.0.0.1',8080)) 8 server.listen(5) 9 server.setblocking(False) 10 11 data_dic={} 12 read_list=[server,] 13 write_list=[] 14 print('start....') 15 while True: 16 # 括號里面應該有四個參數,最后一個參數timeout默認的話就是一直在這邊等待,直到接收到參數。 17 # 如果設置超時延時,那么如果在3s未接受到數據,他會自動運行下面的代碼。但是如果他在1s就接收到數據, 18 # 就會直接執行下面程序。 19 rl,wl,xl=select.select(read_list,write_list,[]) #read_list=[server,conn1,conn2,conn3,conn4] 20 # print('read_list:%s rl:%s wl:%s ' %(len(read_list),len(rl),len(wl))) #rl=[conn1,conn2] 21 for sk in rl: 22 if sk == server: 23 conn,addr=sk.accept() 24 read_list.append(conn) 25 else: 26 # sk.recv(1024) 27 # print(sk) 28 data=sk.recv(1024) 29 write_list.append(sk) 30 data_dic[sk]=data 31 32 for sk in wl: 33 sk.send(data_dic[sk].upper()) 34 data_dic.pop(sk) 35 write_list.remove(sk) 服務端 1 from socket import * 2 import os 3 4 client=socket(AF_INET,SOCK_STREAM) 5 client.connect(('127.0.0.1',8080)) 6 7 while True: 8 msg='%s say hello' %os.getpid() 9 client.send(msg.encode('utf-8')) 10 data=client.recv(1024) 11 print(data.decode('utf-8')) 客戶端?
異步IO
用戶進程發起read操作之后,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當它受到一個asynchronous read之后,首先它會立刻返回,所以不會對用戶進程產生任何block。然后,kernel會等待數據準備完成,然后將數據拷貝到用戶內存,當這一切都完成之后,kernel會給用戶進程發送一個signal,告訴它read操作完成了。流程圖如下:
?
?
上節課復習:1、協程
什么是?
協程指的是單線程下由應用程序級別實現的并發
即把本來由操作系統控制的切換 保存狀態,在應用
程序里實現了
協程的切換vs操作系統的切換
優點:
切換速度遠快于操作系統
缺點:
一個任務阻塞了,其余的任務都無法執行
ps:只有遇到io才切換到其他任務的協程才能提升
單線程的執行效率
為何用?
把單個線程的io降到最低,最大限度地提升單個線程的執行效率
如何實現?
from gevent import spawn,monkey;monkey.patch_all()
2、io模型
block io
nonblocking io
1、對cpu的無效占用率過高
2、不能即時反饋客戶端的信息
?
更多專業前端知識,請上 【猿2048】www.mk2048.com
總結
以上是生活随笔為你收集整理的多路复用IO和异步IO的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: websocket的加密和解密
- 下一篇: re正则表达式公式讲解5