运行 任务创建和异步等待之间的代码
Running code between task creation and await with asyncio
使用 asyncio
是否可以创建一个任务,然后继续执行“主要”代码并稍后等待任务结果?
考虑以下代码
from functools import reduce
import asyncio
async def a_task():
print('a_task(): before sleep')
# waiting for something to happen
await asyncio.sleep(30)
print('a_task(): after sleep')
return 42
async def main():
# Create a Task
print('main() before create_task')
task = asyncio.create_task(a_task())
print('main() task created')
print('Doing stuff here between task creation and await')
# Computing 200000! should take few seconds...
# use a smaller number if its too slow on your machine
x = reduce(lambda a,b: a*b, range(1, 200000))
print('Stuff done')
print('main() awaiting task')
task_result = await task
print('main() task awaited')
return task_result
#%%
if __name__ == '__main__':
results = asyncio.run(main())
print(results)
这个returns
main() before create_task
main() task created
Doing stuff here between task creation and await
Stuff done
main() awaiting task
a_task(): before sleep <<---- Task only starts running here!!
a_task(): after sleep
main() task awaited
42
a_task
是在我们开始计算200000!之前创建的,但它只在我们调用await task
时执行。有没有可能让a_task
开始到运行之前我们开始计算200000!并将其 运行ning 置于后台?
我看了the doc, , this,等等...他们都提到task
应该用来在后台执行代码,但我不明白如何运行 就不用挂主代码了。
我认为这里的问题如下:使用 create_task
创建任务不会安排它立即执行:它需要一个 await
或类似的东西来触发切换事件循环开始 运行 一些不同的东西。在您当前的代码中,任务的创建之后是同步代码,在这种情况下,事件循环无法暂停 main
的执行并启动 运行 任务。确保其行为符合您预期的一种方法是将 asyncio.sleep(0)
放在 运行 阶乘计算之前。这样,当 main()
遇到 await
时,事件循环将暂停执行 main
并切换到 a_task
.
您可能感兴趣的其他方法是使用 asyncio.gather
docs link 安排多个异步任务,然后暂停 main
的执行并等待所有任务完成完成。
from functools import reduce
import asyncio
async def a_task():
print("a_task(): before sleep")
# waiting for something to happen
await asyncio.sleep(30)
print("a_task(): after sleep")
return 42
async def doing_something_else():
print("We start doing something else")
x = reduce(lambda a, b: a * b, range(1, 200000))
print("We finish doing something else")
async def main():
# Create a Task
print("main() before create_task")
task = asyncio.create_task(a_task())
print("main() task created")
print("main() before create_task 2")
task_2 = asyncio.create_task(doing_something_else())
print("main() task 2 created")
print("main() gathering tasks")
# task_result = await task
await asyncio.gather(task, task_2)
print("main() tasks finished")
# return task_result
#%%
if __name__ == "__main__":
results = asyncio.run(main())
print(results)
使用 asyncio
是否可以创建一个任务,然后继续执行“主要”代码并稍后等待任务结果?
考虑以下代码
from functools import reduce
import asyncio
async def a_task():
print('a_task(): before sleep')
# waiting for something to happen
await asyncio.sleep(30)
print('a_task(): after sleep')
return 42
async def main():
# Create a Task
print('main() before create_task')
task = asyncio.create_task(a_task())
print('main() task created')
print('Doing stuff here between task creation and await')
# Computing 200000! should take few seconds...
# use a smaller number if its too slow on your machine
x = reduce(lambda a,b: a*b, range(1, 200000))
print('Stuff done')
print('main() awaiting task')
task_result = await task
print('main() task awaited')
return task_result
#%%
if __name__ == '__main__':
results = asyncio.run(main())
print(results)
这个returns
main() before create_task
main() task created
Doing stuff here between task creation and await
Stuff done
main() awaiting task
a_task(): before sleep <<---- Task only starts running here!!
a_task(): after sleep
main() task awaited
42
a_task
是在我们开始计算200000!之前创建的,但它只在我们调用await task
时执行。有没有可能让a_task
开始到运行之前我们开始计算200000!并将其 运行ning 置于后台?
我看了the doc, task
应该用来在后台执行代码,但我不明白如何运行 就不用挂主代码了。
我认为这里的问题如下:使用 create_task
创建任务不会安排它立即执行:它需要一个 await
或类似的东西来触发切换事件循环开始 运行 一些不同的东西。在您当前的代码中,任务的创建之后是同步代码,在这种情况下,事件循环无法暂停 main
的执行并启动 运行 任务。确保其行为符合您预期的一种方法是将 asyncio.sleep(0)
放在 运行 阶乘计算之前。这样,当 main()
遇到 await
时,事件循环将暂停执行 main
并切换到 a_task
.
您可能感兴趣的其他方法是使用 asyncio.gather
docs link 安排多个异步任务,然后暂停 main
的执行并等待所有任务完成完成。
from functools import reduce
import asyncio
async def a_task():
print("a_task(): before sleep")
# waiting for something to happen
await asyncio.sleep(30)
print("a_task(): after sleep")
return 42
async def doing_something_else():
print("We start doing something else")
x = reduce(lambda a, b: a * b, range(1, 200000))
print("We finish doing something else")
async def main():
# Create a Task
print("main() before create_task")
task = asyncio.create_task(a_task())
print("main() task created")
print("main() before create_task 2")
task_2 = asyncio.create_task(doing_something_else())
print("main() task 2 created")
print("main() gathering tasks")
# task_result = await task
await asyncio.gather(task, task_2)
print("main() tasks finished")
# return task_result
#%%
if __name__ == "__main__":
results = asyncio.run(main())
print(results)