Python asyncio 任务排序 [英] Python asyncio task ordering

查看:71
本文介绍了Python asyncio 任务排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于 python 的 asyncio 模块中的事件循环如何管理未完成任务的问题.考虑以下代码:

I have a question about how the event loop in python's asyncio module manages outstanding tasks. Consider the following code:

import asyncio

@asyncio.coroutine
def a():
   for i in range(0, 3):
      print('a.' + str(i))
      yield


@asyncio.coroutine
def b():
   for i in range(0, 3):
      print('b.' + str(i))
      yield


@asyncio.coroutine
def c():
   for i in range(0, 3):
      print('c.' + str(i))
      yield


tasks = [
   asyncio.Task(a()),
   asyncio.Task(b()),
   asyncio.Task(c()),
]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([t1, t2, t3]))

运行将打印:

a.0
b.0
c.0
a.1
b.1
c.1
a.2
b.2
c.2

请注意,它总是打印出 'a' 然后是 'b' 然后是 'c'.我猜想无论每个协程经过多少次迭代,它都将始终按该顺序打印.所以你永远不会看到类似的东西

Notice that it always prints out 'a' then 'b' then 'c'. I'm guessing that no matter how many iterations each coroutine goes through it will always print in that order. So you'd never see something like

b.100
c.100
a.100

来自 node.js 背景,这告诉我这里的事件循环在内部维护一个队列,它用来决定接下来运行哪个任务.它最初将 a() 放在队列的前面,然后是 b(),然后是 c() 因为这是任务的顺序在传递给 asyncio.wait() 的列表中.然后每当它遇到一个 yield 语句时,它就会将该任务放在队列的末尾.我想在一个更现实的例子中,假设你在做一个异步 http 请求,它会在 http 响应回来后把 a() 放回队列的末尾.

Coming from a node.js background, this tells me that the event loop here is maintaining a queue internally that it uses to decide which task to run next. It initially puts a() at the front of the queue, then b(), then c() since that's the order of the tasks in the list passed to asyncio.wait(). Then whenever it hits a yield statement it puts that task at the end of the queue. I guess in a more realistic example, say if you were doing an async http request, it would put a() back on the end of the queue after the http response came back.

我可以请教一下吗?

推荐答案

目前您的示例不包含任何阻塞 I/O 代码.试试这个来模拟一些任务:

Currently your example doesn't include any blocking I/O code. Try this to simulate some tasks:

import asyncio


@asyncio.coroutine
def coro(tag, delay):
    for i in range(1, 8):
        print(tag, i)
        yield from asyncio.sleep(delay)


loop = asyncio.get_event_loop()

print("---- await 0 seconds :-) --- ")
tasks = [
    asyncio.Task(coro("A", 0)),
    asyncio.Task(coro("B", 0)),
    asyncio.Task(coro("C", 0)),
]

loop.run_until_complete(asyncio.wait(tasks))

print("---- simulate some blocking I/O --- ")
tasks = [
    asyncio.Task(coro("A", 0.1)),
    asyncio.Task(coro("B", 0.3)),
    asyncio.Task(coro("C", 0.5)),
]

loop.run_until_complete(asyncio.wait(tasks))

loop.close()

如您所见,协程是根据需要而不是按顺序安排的.

As you can see, coroutines are scheduled as needed, and not in order.

这篇关于Python asyncio 任务排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆