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 что-то для завершения.

Преимущества заключаются в том, что при встроенной поддержке вы также можете ввести дополнительный синтаксис для поддержки асинхронных контекстных менеджеров и итераторов. Вход и выход из диспетчера контекста или циклический переход по итератору могут стать дополнительными точками в вашей подпрограмме, которые сигнализируют о том, что вместо этого может выполняться другой код, потому что что-то снова ждет.

Другие вопросы по тегам