У меня вопрос о том, как цикл событий в модуле asyncio
python управляет выдающимися задачами. Рассмотрим следующий код:Python asyncio task ordering
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
Обратите внимание, что он всегда печатает «а», то «б», затем «с». Я предполагаю, что независимо от того, сколько итераций проходит каждая сопрограмма, она всегда будет печататься в этом порядке. Таким образом, вы бы никогда не увидеть что-то вроде
b.100
c.100
a.100
Coming из Node.js фона, это говорит мне, что цикл обработки событий здесь поддерживает очередь внутренне, что она использует, чтобы решить, какие задачи для следующего запуска. Сначала он ставит a()
в начале очереди, затем b()
, затем c()
, так как это порядок задач в списке, переданных в asyncio.wait()
. Затем всякий раз, когда он попадает в оператор yield, он ставит эту задачу в конце очереди. Я предполагаю, что в более реалистичном примере скажем, если бы вы выполняли асинхронный HTTP-запрос, он вернул бы a()
в конце очереди после ответа HTTP-ответа.
Могу ли я получить амен на этом?
Правильно, он будет запускать обратные вызовы, как только это будет возможно, если I/O занимает различное количество времени, чтобы завершить, они начнут выходить из строя. Мое мнение состояло в том, что, если не было никаких операций ввода-вывода (как в моем примере), они всегда запускаются в предсказуемом порядке из-за какого-то управления задачами, происходящими за кулисами (возможно, очереди). В отличие от подобных потоков, которые будут запускать их в соответствии с планировщиком потоков ОС и будут непредсказуемыми. – d512
Если нет ввода-вывода, не используйте asyncio. Они не предсказуемы, и вы не можете быть уверены, как это будет работать в другой реализации или версии или в разных условиях. – Udi
Я ценю ответ, но мой вопрос был не в правильном использовании 'asyncio', а в том, как он реализован. Конечно, небезопасно делать предположения о деталях реализации библиотеки, и я не пытаюсь сказать иначе, задавая этот вопрос. Просто хотелось узнать, знает ли кто, как это работает. – d512