Python asyncio异步编程常见问题小结
永远是少年啊 人气:0今天继续给大家介绍Python相关知识,本文主要内容是Python asyncio异步编程常见问题。
一、asyncio编程简单示例
首先,我们来看一段简单的Python asyncio异步编程代码,相关代码如下所示:
import asyncio async def fun(): print(1) await asyncio.sleep(2) print(2) return 3 async def main(): task_list=[ asyncio.create_task(fun()), asyncio.create_task(fun()) ] done,pending=await asyncio.wait(task_list) print(done) asyncio.run(main())
在上述代码中,我们使用了Task列表,将两个fun()协程函数生成的Task对象添加到task列表中,最终实现了这两个函数异步执行。上述代码执行结果如下所示:
二、asyncio编程常见问题
下面,我们想要简单的修改一下上述代码,我们把main()函数删除,尝试直接生成协程对象列表,结果如下所示:
import asyncio async def fun(): print(1) await asyncio.sleep(2) print(2) return 3 task_list=[ asyncio.create_task(fun()), asyncio.create_task(fun()) ] done,pending=asyncio.run(asyncio.wait(task_list)) print(done)
上述代码执行结果如下所示:
三、报错原因及解决方案
从上图中可以看出,上述代码执行报错,错误提示为:RuntimeError:no running event loop。
其实,之所以出现上述报错,直接原因在于当前没有事件循环。当我们使用asyncio模块来实现异步编程时,asyncio模块的优点在于省略了我们创建事件循环的过程,但是这并不意味着asyncio异步编程不需要事件循环。事实上,在第一段代码中,代码:
asyncio.run(main())
在实际上创建了这个事件循环,但是asyncio模块屏蔽了这一细节。而正是因为已经存在了事件循环,因此我们才可以执行命令:
done,pending=await asyncio.wait(task_list)
但是在上述代码中,我们没有创建事件循环,而是直接将该代码放到主程序中执行,因此上述代码会出现报错。
针对上述代码,我们可以简单修改为以下内容:
import asyncio async def fun(): print(1) await asyncio.sleep(2) print(2) return 3 task_list=[ fun(), fun() ] done,pending=asyncio.run(asyncio.wait(task_list)) print(done)
在上述代码中,我们的Task列表中存放的是协程对象,而不是Task对象,这样,我们在执行asyncio.wait时会自动创建一个事件循环,并且把协程对象加入到事件循环中。因此上述代码也就不会报错了。执行结果如下所示:
加载全部内容