PEP 0492 - асинхронное ключевое слово Python 3.5
PEP 0492 добавляет async
Ключевое слово для Python 3.5.
Какую пользу получает Python от использования этого оператора? Пример, который дан для сопрограммы:
async def read_data(db):
data = await db.fetch('SELECT ...')
Согласно документам это достигается
приостановить [ing] выполнение сопрограммы read_data до тех пор, пока db.fetch awaitable не завершит работу и не вернет данные результата.
Является ли это async
Ключевое слово на самом деле включает в себя создание новых потоков или, возможно, использование существующего зарезервированного асинхронного потока?
В случае, если async
использует зарезервированный поток, это один общий поток, каждый из которых имеет свои собственные?
1 ответ
Нет, сопрограммы не связаны с какими-либо потоками. Совместные процедуры допускают совместную многозадачность в том смысле, что каждая совместная процедура дает контроль добровольно. Потоки с другой стороны переключаются между единицами в произвольных точках.
До Python 3.4 можно было писать сопрограммы с использованием генераторов; используя yield
или же yield from
Выражения в теле функции вместо этого вы создаете объект генератора, где код выполняется только тогда, когда вы перебираете генератор. Вместе с дополнительными библиотеками цикла событий (такими как asyncio
) вы могли бы написать сопрограммы, которые бы сигнализировали циклу событий, что они будут заняты (возможно, ожидая ввода-вывода) и что тем временем может быть запущена другая подпрограмма:
import asyncio
import datetime
@asyncio.coroutine
def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(1)
Каждый раз, когда вышеуказанный код переходит к yield from asyncio.sleep(1)
Кроме того, цикл обработки событий может свободно запускать другую подпрограмму, потому что эта процедура все равно ничего не сделает в течение следующей секунды.
Поскольку генераторы могут использоваться для всех видов задач, а не только для подпрограмм, а поскольку написание сопрограммы с использованием синтаксиса генератора может вводить в заблуждение новичков, PEP вводит новый синтаксис, который проясняет, что вы пишете команду. -routine.
При реализации PEP вышеприведенный пример можно записать в виде:
async def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(1)
Результирующий coroutine
объект все еще нуждается в цикле событий для управления сопрограммами; цикл событий будет await
на каждую подпрограмму по очереди, которая будет выполнять те подпрограммы, которые в настоящее время не await
что-то для завершения.
Преимущества заключаются в том, что при встроенной поддержке вы также можете ввести дополнительный синтаксис для поддержки асинхронных контекстных менеджеров и итераторов. Вход и выход из диспетчера контекста или циклический переход по итератору могут стать дополнительными точками в вашей подпрограмме, которые сигнализируют о том, что вместо этого может выполняться другой код, потому что что-то снова ждет.