Подтвердить что ты не робот

PEP 0492 - ключевое слово async для Python 3.5

PEP 0492 добавляет ключевое слово async к Python 3.5.

Как Python извлекает выгоду из использования этого оператора? Пример, предоставленный для сопрограммы,

async def read_data(db):
    data = await db.fetch('SELECT ...')

В соответствии с документами это достигается

приостановить выполнение запроса read_data coroutine до тех пор, пока db.fetch не завершится и не вернет результаты.

Влияет ли это ключевое слово async на создание новых потоков или, возможно, на использование существующего зарезервированного асинхронного потока?

В случае, если async использует зарезервированный поток, является ли он одним общим потоком каждый в своем собственном?

4b9b3361

Ответ 1

Нет, совлокальные подпрограммы не связаны ни с какими потоками. Совлокальные подпрограммы допускают совместную многозадачность в том, что каждая совместная процедура дает контроль на добровольной основе. Нитки, с другой стороны, переключаются между единицами в произвольных точках.

До Python 3.4 можно было писать совлокальные подпрограммы с использованием генераторов; используя выражения yield или yield from в теле функции, вы создаете вместо этого объект-генератор, где код выполняется только тогда, когда вы перебираете генератор. Вместе с дополнительными библиотеками циклов событий (например, asyncio) вы можете написать совлокальные подпрограммы, которые будут сигнализировать о цикле событий, что они будут заняты (ожидание I/O возможно), и что еще одна совместная процедура может быть запущена за это время:

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 вводит новый синтаксис, который делает более понятным, что вы написав совместную программу.

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

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