将 asyncio 用于并行任务

use asyncio for parallel tasks

我想知道如何使用 asyncio 来处理类似于 nodeJS 所做的任务。我想在不打开线程的情况下同时执行 运行 个任务。 示例:

import asyncio

@asyncio.coroutine
def my_coroutine(task_name, seconds_to_sleep=3):
    print('{0} sleeping for: {1} seconds'.format(task_name, seconds_to_sleep))
    yield from asyncio.sleep(seconds_to_sleep)
    print('{0} is finished'.format(task_name))


loop = asyncio.get_event_loop()
tasks = [
    my_coroutine('task1', 4),
    my_coroutine('task2', 3),
    my_coroutine('task3', 2)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

将输出:

task1 sleeping for: 4 seconds
task2 sleeping for: 3 seconds
task3 sleeping for: 2 seconds
task3 is finished
task2 is finished
task1 is finished

但是当我尝试用不同的任务来完成它时,它不会那样工作。

import asyncio
import timeit

@asyncio.coroutine
def my_coroutine(task_name):
    print('order placed for ' + task_name)
    print(timeit.timeit('1 + 3 ', number=50000000))
    print(task_name + ' done')


loop = asyncio.get_event_loop()
tasks = [
    my_coroutine('task1'),
    my_coroutine('task2'),
    my_coroutine('task3')]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

产出

order placed for task2
0.6677237730912453
task2 done
order placed for task1
0.6627442526498016
task1 done
order placed for task3
0.665618849882418
task3 done

asyncio 不会 运行 并行处理。它 运行 是一个任务,直到它等待,然后才转到下一个任务。第一个示例中的 sleep 是使任务相互产生控制的原因。你的第二个例子不等待任何东西,所以每个任务 运行s 直到事件循环可以控制另一个任务之前完成。

如果你在你的协程中添加一些可等待的东西(例如,asyncio.sleep),每个人都会放弃控制权,让其他人有机会 运行。

@asyncio.coroutine
def my_coroutine(task_name):
    print('order placed for ' + task_name)
    yield from asyncio.sleep(0)  # Another coroutine will resume here.
    print(timeit.timeit('1 + 3 ', number=50000000))
    yield from asyncio.sleep(0)  # Another coroutine will resume here.
    print(task_name + ' done')