一、概述
asyncio 是用來編寫 並發 代碼的庫,使用 async/await 語法。
asyncio 被用作多個提供高性能 Python 異步框架的基礎,包括網絡和網站服務,數據庫連接庫,分布式任務隊列等等。
asyncio 往往是構建 IO 密集型和高層級 結構化 網絡代碼的最佳選擇。
asyncio 提供一組 高層級 API 用於:
-
並發地 運行 Python 協程 並對其執行過程實現完全控制;
-
執行 網絡 IO 和 IPC;
-
控制 子進程;
-
通過 隊列 實現分布式任務;
-
同步 並發代碼;
此外,還有一些 低層級 API 以支持 庫和框架的開發者 實現:
-
使用 transports 實現高效率協議;
-
通過 async/await 語法 橋接 基於回調的庫和代碼。
關於asyncio的使用,請閱讀以下2篇文章:
https://blog.csdn.net/SL_World/article/details/86597738
https://blog.csdn.net/SL_World/article/details/86691747
寫的非常不錯,強烈推薦!!!
二、功能演示
subprocess
需求
需要ping內網中的所有ip地址,是否都可以pnig通。
內網網段為:192.168.31.0/24
完整代碼
test.py

#!/usr/bin/env python3 # coding: utf-8 import time import subprocess import asyncio import re async def ping_call(num): # 當前時間 current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) ip = "192.168.31.%s" % num # 超時時間為1秒,ping 1次 cmd = 'ping -c 1 -w 1 -W 1 %s' % ip print(cmd) # 執行命令 proc = await asyncio.create_subprocess_exec('ping', '-c', '1','-w','1','-W','1', ip, stdout=asyncio.subprocess.PIPE) # print("proc",proc,type(proc)) result = await proc.stdout.read() # 通過正則匹配是否有100%關鍵字 regex = re.findall('100% packet loss', result.decode('utf-8')) # 長度為0時,表示沒有出現100% packet loss if len(regex) == 0: return current_time,ip,True else: return current_time,ip,False async def main(): # 調用方 tasks = [] for i in range(1, 256): # 把所有任務添加到task中 tasks.append(ping_call(i)) # 子生成器 done, pending = await asyncio.wait(tasks) # done和pending都是一個任務,所以返回結果需要逐個調用result() for r in done: # print(r.result()) # 判斷布爾值 if r.result()[2]: # 顏色代碼 color_code = 32 else: color_code = 31 info = "\033[1;{};1m{}\033[0m".format(color_code, r.result()) print(info) if __name__ == '__main__': start = time.time() # 創建一個事件循環對象loop loop = asyncio.get_event_loop() try: # 完成事件循環,直到最后一個任務結束 loop.run_until_complete(main()) finally: # 結束事件循環 loop.close() print('所有IO任務總耗時%.5f秒' % float(time.time() - start))
執行輸出:
... ping -c 1 -w 1 -W 1 192.168.31.11 ... ('2020-04-20 18:18:21', '192.168.31.138', False) ('2020-04-20 18:18:21', '192.168.31.230', True) ('2020-04-20 18:18:21', '192.168.31.1', True) ('2020-04-20 18:18:20', '192.168.31.170', False) ... ('2020-04-20 18:18:20', '192.168.31.200', False) 所有IO任務總耗時1.93505秒
可以發現,花費時間為1.9秒。速度特別快!
如果同步執行,可能需要500多秒。
注意:subprocess模塊,是調用asyncio.create_subprocess_exec,它返回一個asyncio生成器對象。
如果直接調用python自帶的subprocess模塊,是無法實現異步的。
本文參考鏈接:
https://gist.github.com/athoune/0736f73368fac38f066ac7cbf82ff5eb
http://codingdict.com/sources/py/asyncio/5789.html