2016-11-12 2 views
1

Я играю с модулем 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

Вы вызываете функции последовательно, поэтому код также выполняется последовательно. Помните, что await this означает «doи wait для его возврата» (но в то же время, если 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

Вы столкнулись с общим источником путаницы с await заявлениями, что они ведут себя последовательно для «ребенка» coroutines, но они ведут себя в асинхронном режиме для «соседних» coroutines.

Например:

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