asyncio 是用来编写 并发 代码的库,使用 async/await 语法。
asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。
asyncio 往往是构建 IO 密集型和高层级 结构化 网络代码的最佳选择。
asyncio 提供一组 高层级 API 用于:
并发地 运行 Python 协程 并对其执行过程实现完全控制;
执行 网络 IO 和 IPC;
控制 子进程;
通过 队列 实现分布式任务;
同步 并发代码;
此外,还有一些 低层级 API 以支持 库和框架的开发者 实现:
创建和管理 事件循环,以提供异步 API 用于
网络化
, 运行子进程
,处理OS 信号
等等;使用 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