Asyncio不会异步执行任务

时间:2016-11-12 14:53:43

标签: python asynchronous synchronization python-asyncio

我正在使用Python的asyncio模块,我不知道我的简单代码有什么问题。它不会异步执行任务。

#!/usr/bin/env python3    

import asyncio
import string    


async def print_num():
    for x in range(0, 10):
        print('Number: {}'.format(x))
        await asyncio.sleep(1)    

    print('print_num is finished!')    

async def print_alp():
    my_list = string.ascii_uppercase    

    for x in my_list:
        print('Letter: {}'.format(x))
        await asyncio.sleep(1)    

    print('print_alp is finished!')    


async def msg(my_msg):
    print(my_msg)
    await asyncio.sleep(1)    


async def main():
    await msg('Hello World!')
    await print_alp()
    await msg('Hello Again!')
    await print_num()    


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

以下是调用脚本时的输出:

Hello World!
Letter: A
Letter: B
Letter: C
Letter: D
Letter: E
Letter: F
Letter: G
Letter: H
Letter: I
Letter: J
Letter: K
Letter: L
Letter: M
Letter: N
Letter: O
Letter: P
Letter: Q
Letter: R
Letter: S
Letter: T
Letter: U
Letter: V
Letter: W
Letter: X
Letter: Y
Letter: Z
print_alp is finished!
Hello Again!
Number: 0
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Number: 6
Number: 7
Number: 8
Number: 9
print_num is finished!

2 个答案:

答案 0 :(得分:3)

您正在按顺序调用函数,因此代码也会按顺序执行。请记住,await this表示“执行this等待让它返回”(但与此同时,如果this选择暂停执行,则其他任务已在其他地方开始可能会运行。)

如果要异步运行任务,则需要:

async def main():
    await msg('Hello World!')
    task1 = asyncio.ensure_future(print_alp())
    task2 = asyncio.ensure_future(print_num())
    await asyncio.gather(task1, task2)
    await msg('Hello Again!')

另请参阅asyncio.gather函数的文档。或者,您也可以使用asyncio.wait

答案 1 :(得分:1)

您遇到了与await语句混淆的常见原因,即它们对“子”coroutines按顺序行事,但它们与“邻居”coroutines的行为异步。< / p>

例如:

import asyncio

async def child():
    i = 5
    while i > 0:
        print("Hi, I'm the child coroutine, la la la la la")
        await asyncio.sleep(1)
        i -= 1

async def parent():
    print("Hi, I'm the parent coroutine awaiting the child coroutine")
    await child() # this blocks inside the parent coroutine, but not the neighbour
    print("Hi, I'm the parent, the child coroutine is now done and I can stop waiting")

async def neighbour():
    i = 5
    while i > 0:
        await asyncio.sleep(1)
        print("Hi, I'm your neighbour!")
        i -= 1

async def my_app():
    # start the neighbour and parent coroutines and let them coexist in Task wrappers
    await asyncio.wait([neighbour(), parent()])

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(my_app())

将输出:

Hi, I'm the parent coroutine awaiting the child coroutine
Hi, I'm the child coroutine, la la la la la
Hi, I'm the child coroutine, la la la la la
Hi, I'm your neighbour!
Hi, I'm the child coroutine, la la la la la
Hi, I'm your neighbour!
Hi, I'm the child coroutine, la la la la la
Hi, I'm your neighbour!
Hi, I'm the child coroutine, la la la la la
Hi, I'm your neighbour!
Hi, I'm the parent, the child coroutine is now done and I can stop waiting
Hi, I'm your neighbour!

Process finished with exit code 0