我的代码:
import asyncio
from random import randrange
async def inner_sleep(letter, num):
print(f'start inner sleep {letter}, {num}')
myint = randrange(5)
await asyncio.sleep(myint)
print(f'done with inner sleep {letter}, {num}')
async def outer_sleep(letter):
print(f'start outer sleep {letter}')
myint = randrange(5)
await asyncio.sleep(myint)
print(f'done with outer sleep {letter}')
async def inside(letter):
nums = [1,2,3,4,5,6]
tasks = []
async def create_task(num):
task = asyncio.ensure_future(inner_sleep(letter, num))
tasks.append(task)
for num in nums:
await create_task(num)
await asyncio.gather(*tasks)
async def outside():
letters = ['a','b','c','d']
tasks = []
async def create_task_1(letter):
task = asyncio.ensure_future(outer_sleep(letter))
tasks.append(task)
for letter in letters:
await create_task_1(letter)
await inside(letter)
await asyncio.gather(*tasks)
asyncio.run(outside())
示例输出:
start outer sleep a
start inner sleep a, 1
start inner sleep a, 2
start inner sleep a, 3
start inner sleep a, 4
start inner sleep a, 5
start inner sleep a, 6
done with inner sleep a, 4
done with outer sleep a
done with inner sleep a, 2
done with inner sleep a, 3
done with inner sleep a, 1
done with inner sleep a, 5
done with inner sleep a, 6
start outer sleep b
start inner sleep b, 1
start inner sleep b, 2
start inner sleep b, 3
start inner sleep b, 4
start inner sleep b, 5
start inner sleep b, 6
done with inner sleep b, 3
done with inner sleep b, 5
done with inner sleep b, 4
done with outer sleep b
done with inner sleep b, 1
done with inner sleep b, 6
done with inner sleep b, 2
start outer sleep c
start inner sleep c, 1
我在循环中有一个循环,我希望它们都异步运行。内部工作正常,但我无法让外部做我想做的事。在上面的代码中,我希望我的外部函数同时循环遍历列表“字母”。对于每个字母,我需要在第二个函数 (inner_sleep) 启动之前完成第一个函数 (outer_sleep)。我似乎找不到放置内部函数的地方来完成此操作。当我运行此代码时,您可以在结果中看到“内部睡眠 a”如何在“外部睡眠 a 完成”之前开始。理想情况下,我的输出看起来像:
start outer sleep a
start outer sleep b
finish outer sleep a
start inner sleep a, 1
start inner sleep a, 2
start inner sleep a, 3
start inner sleep a, 4
start inner sleep a, 5
start inner sleep a, 6
finish outer sleep b
start inner sleep b, 1
start inner sleep b, 2
start inner sleep b, 3
start inner sleep b, 4
start inner sleep b, 5
start inner sleep b, 6
done with inner sleep a, 4
done with inner sleep a, 2
done with inner sleep b, 3
这可能吗?
答案 0 :(得分:0)
在 create_task_1
中,您正在调用 outer_sleep
但您没有 await
结果。这意味着任务已启动,但 outside
函数的执行在它完成之前继续进行。
您需要 create_task_1
函数有什么理由吗?你可以直接await outer_sleep(letter)
吗?例如(注意这是未经测试的):
async def outside():
letters = ['a','b','c','d']
# don't need create_task_1 funciton anymore
for letter in letters:
await outer_sleep(letter)
await inside(letter)
# don't need to gather the tasks as they're already complete
编辑:
您在评论中阐明您希望所有 outer_sleep
任务同时开始。你只需要稍微翻转一下执行顺序
async def outside():
letters = ['a','b','c','d']
tasks = []
async def task_1(letter):
await outer_sleep(letter)
await inside(letter)
for letter in letters:
task = asyncio.ensure_future(task_1(letter))
tasks.append(task)
await asyncio.gather(*tasks)
答案 1 :(得分:0)
将 await inside(letter)
放在 outer_sleep
的末尾怎么样?这确保它只会在特定 outer_sleep
的结果到达后才运行。
import asyncio
from random import randrange
async def inner_sleep(letter, num):
print(f'start inner sleep {letter}, {num}')
myint = randrange(5)
await asyncio.sleep(myint)
print(f'done with inner sleep {letter}, {num}')
async def inside(letter):
nums = [1, 2, 3, 4, 5, 6]
tasks = [asyncio.ensure_future(inner_sleep(letter, num)) for num in nums]
await asyncio.gather(*tasks)
async def outer_sleep(letter):
print(f'start outer sleep {letter}')
myint = randrange(5)
await asyncio.sleep(myint)
print(f'done with outer sleep {letter}')
await inside(letter)
async def outside():
letters = ['a', 'b', 'c', 'd']
tasks = [asyncio.ensure_future(outer_sleep(letter)) for letter in letters]
await asyncio.gather(*tasks)
asyncio.run(outside())
asyncio.gather
表示数字和字母都可以按任何顺序处理(例如,'c' 可以在 'b' 之前),如果您可以接受的话。