一、什麼是協程 引例: import time # 串列執行計算密集型的任務 1.2372429370880127 def func1(): for i in range(10000000): i + 1 def func2(): for i in range(10000000): i + 1 st ...
一、什麼是協程
引例:
import time # 串列執行計算密集型的任務 1.2372429370880127 def func1(): for i in range(10000000): i + 1 def func2(): for i in range(10000000): i + 1 start_time = time.time() func1() func2() print(time.time() - start_time) 切換 + yield 2.1247239112854004 import time def func1(): while True: 10000000 + 1 yield def func2(): g = func1() # 先初始化出生成器 for i in range(10000000): i + 1 next(g) start_time = time.time() func2() print(time.time() - start_time)串列執行
1、協程:
# 單線程實現併發,在應用程式里控制多個任務的切換+保存狀態
# 優點:應用程式級別速度要遠遠高於操作系統的切換
# 缺點:
多個任務一旦有一個阻塞沒有切,整個線程都阻塞在原地,該線程內的其他的任務都不能執行了
一旦引入協程,就需要檢測單線程下所有的IO行為, 實現遇到IO就切換,少一個都不行,
以為一旦一個任務阻塞了,整個線程就阻塞了, 其他的任務即便是可以計算,但是也無法運行了
2、協程式的目的: 想要在單線程下實現併發 併發指的是多個任務看起來是同時運行的 併發=切換+保存狀態
二、gevent模塊-應用舉例:
from gevent import monkey;monkey.patch_all() import time from gevent import spawn """ gevent模塊本身無法檢測常見的一些io操作 在使用的時候需要你額外的導入一句話 from gevent import monkey monkey.patch_all() 又由於上面的兩句話在使用gevent模塊的時候是肯定要導入的 所以還支持簡寫 from gevent import monkey;monkey.patch_all() """ def heng(): print('哼') time.sleep(2) print('哼') def ha(): print('哈') time.sleep(3) print('哈') def heiheihei(): print('heiheihei') time.sleep(5) print('heiheihei') start_time = time.time() g1 = spawn(heng) g2 = spawn(ha) g3 = spawn(heiheihei) g1.join() g2.join() # 等待被檢測的任務執行完畢 再往後繼續執行 g3.join() # heng() # ha() # print(time.time() - start_time) # 5.005702018737793 print(time.time() - start_time) # 3.004199981689453 5.005439043045044gevent模塊
三、協程實現TCP服務端併發
from gevent import monkey;monkey.patch_all() import socket from gevent import spawn def communication(conn): while True: try: data = conn.recv(1024) if len(data) == 0: break conn.send(data.upper()) except ConnectionResetError as e: print(e) break conn.close() def server(ip, port): server = socket.socket() server.bind((ip, port)) server.listen(5) while True: conn, addr = server.accept() spawn(communication, conn) if __name__ == '__main__': g1 = spawn(server, '127.0.0.1', 8080) g1.join()View Code
參考閱讀:
https://www.cnblogs.com/linhaifeng/articles/7429894.html