如何在Python中永久运行异步函数?
如何用asyncio实现函数的永久运行&启动异步函数
我来帮你理清这几个点:如何启动你的异步函数,以及run_forever的具体用法,还有实现永久运行的两种常见方式。
首先,先解决启动异步函数的基础问题:你的someFunction是一个异步协程,不能直接调用(直接调用只会返回一个协程对象,不会执行),必须把它交给asyncio的事件循环来运行。
1. 基础启动:运行一次异步函数
如果你只是想运行一次这个函数,可以用run_until_complete,代码示例如下:
import asyncio # 假设something是一个异步上下文管理器,比如asyncio.Lock() async def someFunction(): async with asyncio.Lock() as some_variable: print("执行一次任务") await asyncio.sleep(1) # 模拟异步操作 # 获取事件循环 loop = asyncio.get_event_loop() try: # 让事件循环运行直到协程完成 loop.run_until_complete(someFunction()) finally: # 关闭事件循环,释放资源 loop.close()
2. 实现函数永久运行的两种方式
如果要让函数持续运行不停止,有两种常用思路:
方式一:让协程自身无限循环 + run_until_complete
在你的异步函数里加入while True循环,这样协程永远不会执行完毕,run_until_complete就会一直运行事件循环:
import asyncio async def someFunction(): while True: # 无限循环,让函数永久运行 async with asyncio.Lock() as some_variable: print("正在重复执行任务...") await asyncio.sleep(1) # 必须加await,否则会阻塞事件循环 loop = asyncio.get_event_loop() try: loop.run_until_complete(someFunction()) except KeyboardInterrupt: print("收到中断信号,停止运行") finally: loop.close()
注意:循环里必须包含
await语句(比如asyncio.sleep),否则会占用100% CPU,因为事件循环被阻塞无法处理其他任务。
方式二:使用run_forever管理事件循环
run_forever的作用是让事件循环一直运行,直到你手动调用loop.stop()。要让你的函数永久运行,需要先把它注册为事件循环的任务:
import asyncio async def someFunction(): while True: async with asyncio.Lock() as some_variable: print("在run_forever模式下运行任务...") await asyncio.sleep(1) loop = asyncio.get_event_loop() # 创建任务并加入事件循环 task = loop.create_task(someFunction()) try: # 启动事件循环,永久运行 loop.run_forever() except KeyboardInterrupt: print("收到中断信号,开始清理") # 取消任务,避免资源泄漏 task.cancel() # 等待任务完成取消过程 loop.run_until_complete(task) finally: loop.close()
这里的关键是:run_forever不会自动执行协程,必须先通过loop.create_task()(或asyncio.ensure_future())把协程包装成任务,事件循环才会在运行时执行它。
3. Python 3.7+ 简化写法
从Python 3.7开始,asyncio.run()函数可以帮你自动创建、运行和关闭事件循环,代码更简洁:
import asyncio async def someFunction(): while True: async with asyncio.Lock() as some_variable: print("用asyncio.run()运行永久任务...") await asyncio.sleep(1) async def main(): await someFunction() # 等待无限循环的协程 asyncio.run(main())
asyncio.run()内部会调用run_until_complete运行main协程,而main会一直等待someFunction,所以程序会永久运行直到被中断。
内容的提问来源于stack exchange,提问作者Tearzz
相关产品推荐
相关产品推荐

