Python异步编程:asyncio库的使用说明,以及和multiprocessing 的性能对比(2分钟立马掌握)
关于同步和异步的理解:
当我执行一段程序时,不仅需要CPU处理,还需要硬盘、网络等IO操作。而事实是,CPU的速度远大于IO操作速度。
假设:此时有个程序的过程是,CPU处理--IO操作--CPU处理,进过三次操作才能完成。但是在进行IO操作时,程序就卡住了(因为太慢了)。
如果你写程序的逻辑是:先完成整个的------CPU处理--IO操作--CPU处理,才能进行下一个线程,那么,你的程序就是同步的。
如果你写程序的逻辑是:第一个线程先完成CPU处理,传递给IO操作,此时虽然卡住了,但是可以进行第二个线程再次从CPU处理开始。等第一个IO操作完成后,再交给CPU处理。第二个IO操作完成后,再交给CPU处理。这样你的程序就是异步的。
代码实现和对比
我们用几种不同的方式来运行---打印20个时间戳。
第一轮:同步的方式(我们刚学编程时,普遍的思维方式):即打印一个时间戳后停顿1秒。
import time
def hello():
time.sleep(1)
def run():
for i in range(10):
hello()
print('Hello World:%s' % time.time())
if __name__ == '__main__':
run()
可以看到输出如下:确实是间隔一秒后输出结果。前后十个线程间隔为:9秒
第二轮:异步的方式,用到 multiprocessing 库:这也是个异步的库。
import time
from multiprocessing.pool import Pool
def hello():
time.sleep(1)
def run(i):
hello()
print('Hello World:%s' % time.time())
if __name__ == '__main__':
pool = Pool()
pool.map(run,[i for i in range(10)])
最终可以看到输出结果,前后十个进程间隔为:0.107秒
第三轮:异步的方式。使用asyncio库。
import time
import asyncio
# 这是定义异步函数,先记住写法即可
async def hello():
asyncio.sleep(1)
print('Hello World:%s' % time.time())
def run():
for i in range(10):
loop.run_until_complete(hello()) # 这是让这个事件一直处理下去,直到结束后再提交给下一步、进行该线程的剩余操作。
loop = asyncio.get_event_loop() # 这是创建一个事件循环,可以理解为类中的,实例化的概念
if __name__ == '__main__':
run()
最后的结果如下,前后十个线程的间隔为:0.001 秒
总结:
从以上测试可以看到同步和异步在性能上的差别还是很大的,如果程序更复杂,他们之间的差异会更大。
至于异步常用的库 multiprocessing 和asyncio 间,后者效率更高些,具体的差异细节,大家可以做更深入的测试进行调试。