> **Источник:** https://python-all.ru/3.6/library/asyncio-eventloop.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 18.5.1. Базовый цикл событий

**Исходный код:** [Lib/asyncio/events.py](https://python-all.ru/src/3.6/Lib/asyncio/events.py)

Цикл событий – это центральное исполнительное устройство, предоставляемое модулем [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio). Он предоставляет множество возможностей, в том числе:

- Регистрация, выполнение и отмена отложенных вызовов (тайм-аутов).
- Создание [транспортов](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-transport) клиента и сервера для различных видов взаимодействия.
- Запуск подпроцессов и связанных с ними [транспортов](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-transport) для взаимодействия с внешней программой.
- Делегирование дорогостоящих вызовов функций пулу потоков.

#### `class asyncio.BaseEventLoop`

Этот класс является деталью реализации. Он является подклассом [`AbstractEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop) и может быть базовым классом конкретных реализаций цикла событий, находящихся в [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio). Его не следует использовать напрямую; вместо этого используйте [`AbstractEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop). `BaseEventLoop` не должен наследоваться сторонним кодом; внутренний интерфейс нестабилен.

#### `class asyncio.AbstractEventLoop`

Абстрактный базовый класс циклов событий.

This class is [не является потокобезопасным](https://python-all.ru/3.6/library/asyncio-dev.html#asyncio-multithreading).

## 18.5.1.1. Запуск цикла событий

#### `AbstractEventLoop.run_forever()`

Выполняется до вызова [`stop()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.stop). Если [`stop()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.stop) вызывается до вызова [`run_forever()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever), то однократно опрашивается I/O-селектор с нулевым тайм-аутом, выполняются все колбэки, запланированные в ответ на I/O-события (а также уже запланированные), после чего происходит выход. Если [`stop()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.stop) вызывается во время выполнения [`run_forever()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever), то будет выполнен текущий набор колбэков, после чего произойдёт выход. Обратите внимание, что колбэки, запланированные другими колбэками, в этом случае не выполнятся; они выполнятся при следующем вызове [`run_forever()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever).

Изменено в версии 3.5.1.

#### `AbstractEventLoop.run_until_complete(future)`

Выполняется до завершения [`Future`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.Future).

Если аргумент является [объектом корутины](https://python-all.ru/3.6/library/asyncio-task.html#coroutine), он оборачивается с помощью [`ensure_future()`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.ensure_future).

Возвращает результат Future или возбуждает его исключение.

#### `AbstractEventLoop.is_running()`

Возвращает статус выполнения цикла событий.

#### `AbstractEventLoop.stop()`

Останавливает выполнение цикла событий.

Это приводит к выходу из [`run_forever()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever) при следующей удобной возможности (см. там подробнее).

Изменено в версии 3.5.1.

#### `AbstractEventLoop.is_closed()`

Возвращает `True`, если цикл событий был закрыт.

Новое в версии 3.4.2.

#### `AbstractEventLoop.close()`

Закрывает цикл событий. Цикл не должен выполняться. Ожидающие колбэки будут потеряны.

Это очищает очереди и завершает работу исполнителя, но не дожидается его полной остановки.

Это идемпотентно и необратимо. После этого метода не следует вызывать никакие другие методы.

#### `coroutine AbstractEventLoop.shutdown_asyncgens()`

Планирует закрытие всех текущих открытых [асинхронных генераторов](https://python-all.ru/3.6/glossary.html#term-asynchronous-generator) с помощью вызова [`aclose()`](https://python-all.ru/3.6/reference/expressions.html#agen.aclose). После вызова этого метода цикл событий будет выдавать предупреждение при каждой итерации нового асинхронного генератора. Следует использовать для надёжного завершения всех запланированных асинхронных генераторов. Пример:

```python
try:
    loop.run_forever()
finally:
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()
```

Новое в версии 3.6.

## 18.5.1.2. Вызовы

Большинство функций [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio) не принимают именованные аргументы. Если вы хотите передать именованные аргументы в свой колбэк, используйте [`functools.partial()`](https://python-all.ru/3.6/library/functools.html#functools.partial). Например, `loop.call_soon(functools.partial(print, "Hello", flush=True))` вызовет `print("Hello", flush=True)`.

> **Примечание**
>
> [`functools.partial()`](https://python-all.ru/3.6/library/functools.html#functools.partial) лучше, чем функции `lambda`, потому что [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio) может проверять объект [`functools.partial()`](https://python-all.ru/3.6/library/functools.html#functools.partial) для отображения параметров в режиме отладки, в то время как функции `lambda` имеют плохое представление.

#### `AbstractEventLoop.call_soon(callback, *args)`

Планирует вызов колбэка как можно скорее. Колбэк вызывается после возврата [`call_soon()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon), когда управление возвращается в цикл событий.

Эта очередь работает по принципу FIFO; колбэки вызываются в порядке их регистрации. Каждый колбэк будет вызван ровно один раз.

Любые позиционные аргументы, указанные после колбэка, будут переданы ему при вызове.

Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.

[Используйте functools.partial для передачи именованных аргументов колбэку](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-pass-keywords).

#### `AbstractEventLoop.call_soon_threadsafe(callback, *args)`

Аналогично [`call_soon()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon), но потокобезопасно.

См. раздел [concurrency and multithreading](https://python-all.ru/3.6/library/asyncio-dev.html#asyncio-multithreading) документации.

## 18.5.1.3. Отложенные вызовы

Цикл событий имеет собственные внутренние часы для вычисления тайм-аутов. Какие именно часы используются, зависит от реализации цикла событий (зависящей от платформы); в идеале это монотонные часы. Обычно это другие часы, нежели [`time.time()`](https://python-all.ru/3.6/library/time.html#time.time).

> **Примечание**
>
> Тайм-ауты (относительная *задержка* или абсолютное *время*) не должны превышать одних суток.

#### `AbstractEventLoop.call_later(delay, callback, *args)`

Организует вызов *колбэка* через заданную *задержку* в секундах (целое число или float).

Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.

*Колбэк* будет вызван ровно один раз на каждый вызов [`call_later()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later). Если два колбэка запланированы на одно и то же время, порядок их вызова не определён.

Необязательные позиционные *args* будут переданы колбэку при его вызове. Если нужно передать колбэку именованные аргументы, используйте замыкание или [`functools.partial()`](https://python-all.ru/3.6/library/functools.html#functools.partial).

[Используйте functools.partial для передачи именованных аргументов колбэку](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-pass-keywords).

#### `AbstractEventLoop.call_at(when, callback, *args)`

Организует вызов *колбэка* в указанную абсолютную метку времени *when* (целое число или float), используя ту же систему отсчёта времени, что и [`AbstractEventLoop.time()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.time).

Поведение этого метода аналогично [`call_later()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later).

Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.

[Используйте functools.partial для передачи именованных аргументов колбэку](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-pass-keywords).

#### `AbstractEventLoop.time()`

Возвращает текущее время в виде значения [`float`](https://python-all.ru/3.6/library/functions.html#float) в соответствии с внутренними часами цикла событий.

> **См. также**
>
> Функция [`asyncio.sleep()`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.sleep).

## 18.5.1.4. Future

#### `AbstractEventLoop.create_future()`

Создаёт объект [`asyncio.Future`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.Future), привязанный к циклу событий.

Это предпочтительный способ создания Future-объектов в asyncio, поскольку реализации цикла событий могут предоставлять альтернативные реализации класса Future (с улучшенной производительностью или инструментарием).

Новое в версии 3.5.2.

## 18.5.1.5. Задачи

#### `AbstractEventLoop.create_task(coro)`

Планирует выполнение [объекта корутины](https://python-all.ru/3.6/library/asyncio-task.html#coroutine): оборачивает его в future. Возвращает объект [`Task`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.Task).

Сторонние циклы событий могут использовать собственный подкласс [`Task`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.Task) для взаимодействия. В этом случае тип результата – подкласс [`Task`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.Task).

Этот метод был добавлен в Python 3.4.2. Используйте функцию [`async()`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.async) для поддержки более старых версий Python.

Новое в версии 3.4.2.

#### `AbstractEventLoop.set_task_factory(factory)`

Устанавливает фабрику задач, которая будет использоваться [`AbstractEventLoop.create_task()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task).

Если *factory* равно `None`, будет установлена фабрика задач по умолчанию.

Если *factory* является *вызываемым объектом*, его сигнатура должна соответствовать `(loop, coro)`, где *loop* – ссылка на активный цикл событий, *coro* – объект корутины. Вызываемый объект должен возвращать объект, совместимый с [`asyncio.Future`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.Future).

Новое в версии 3.4.4.

#### `AbstractEventLoop.get_task_factory()`

Возвращает фабрику задач или `None`, если используется стандартная.

Новое в версии 3.4.4.

## 18.5.1.6. Создание соединений

#### `coroutine AbstractEventLoop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None)`

Создаёт потоковое транспортное соединение с указанными интернет-хостом *host* и портом *port*: семейство сокетов [`AF_INET`](https://python-all.ru/3.6/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.6/library/socket.html#socket.AF_INET6) в зависимости от *host* (или *family*, если указано), тип сокета [`SOCK_STREAM`](https://python-all.ru/3.6/library/socket.html#socket.SOCK_STREAM). *protocol\_factory* должен быть вызываемым объектом, возвращающим экземпляр [протокола](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-protocol).

Этот метод является [корутиной](https://python-all.ru/3.6/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(transport, protocol)`.

Хронологическая последовательность выполняемой операции следующая:

1. Соединение установлено, и создаётся [транспорт](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-transport), представляющий его.
2. *protocol\_factory* вызывается без аргументов и должен возвращать экземпляр [протокола](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-protocol).
3. Экземпляр протокола привязывается к транспорту, и вызывается его метод `connection_made()`.
4. Корутина успешно возвращает пару `(transport, protocol)`.

Созданный транспорт является двунаправленным потоком, зависящим от реализации.

> **Примечание**
>
> *protocol\_factory* может быть любым вызываемым объектом, не обязательно классом. Например, если нужно использовать уже созданный экземпляр протокола, можно передать `lambda: my_protocol`.

Параметры, изменяющие способ создания соединения:

- *ssl*: если указан и не равен false, создаётся SSL/TLS транспорт (по умолчанию создаётся обычный TCP транспорт). Если *ssl* является объектом [`ssl.SSLContext`](https://python-all.ru/3.6/library/ssl.html#ssl.SSLContext), этот контекст используется для создания транспорта; если *ssl* равен [`True`](https://python-all.ru/3.6/library/constants.html#True), используется контекст с некоторыми неопределёнными настройками по умолчанию.

  > **См. также**
  >
  > [Вопросы безопасности SSL/TLS](https://python-all.ru/3.6/library/ssl.html#ssl-security)
- *server\_hostname* используется только вместе с *ssl* и задаёт или переопределяет имя хоста, с которым будет сравниваться сертификат целевого сервера. По умолчанию используется значение аргумента *host*. Если *host* пуст, значение по умолчанию отсутствует, и необходимо передать значение для *server\_hostname*. Если *server\_hostname* является пустой строкой, проверка имени хоста отключается (что представляет серьёзную угрозу безопасности, допуская атаки man-in-the-middle).
- *family*, *proto*, *flags* – необязательные семейство адресов, протокол и флаги, которые передаются в getaddrinfo() для разрешения *host*. Если заданы, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.6/library/socket.html#module-socket).
- Если задан *sock*, он должен быть существующим, уже подключённым объектом [`socket.socket`](https://python-all.ru/3.6/library/socket.html#socket.socket), который будет использоваться транспортом. Если *sock* задан, ни один из параметров *host*, *port*, *family*, *proto*, *flags* и *local\_addr* не должен быть указан.
- *local\_addr*, если указан, представляет собой кортеж `(local_host, local_port)`, используемый для локальной привязки сокета. *local\_host* и *local\_port* ищутся с помощью getaddrinfo(), аналогично *host* и *port*.

Изменено в версии 3.5: В Windows с [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) теперь поддерживается SSL/TLS.

> **См. также**
>
> Функция [`open_connection()`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.open_connection) может использоваться для получения пары ([`StreamReader`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.StreamReader), [`StreamWriter`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.StreamWriter)) вместо протокола.

#### `coroutine AbstractEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_address=None, reuse_port=None, allow_broadcast=None, sock=None)`

> **Примечание**
>
> Параметр *reuse\_address* больше не поддерживается, так как использование `SO_REUSEADDR` создаёт серьёзную угрозу безопасности для UDP. Явная передача `reuse_address=True` вызовет исключение.
>
> Когда несколько процессов с разными UID назначают сокеты одному и тому же адресу UDP-сокета с помощью `SO_REUSEADDR`, входящие пакеты могут случайным образом распределяться между сокетами.
>
> На поддерживаемых платформах *reuse\_port* можно использовать как замену аналогичной функциональности. С *reuse\_port* используется `SO_REUSEPORT`, что не позволяет процессам с разными UID назначать сокеты на один и тот же адрес сокета.

Создать датаграммное соединение.

Создание датаграммного соединения: семейство сокетов [`AF_INET`](https://python-all.ru/3.6/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.6/library/socket.html#socket.AF_INET6) в зависимости от *host* (или *family*, если указано), тип сокета [`SOCK_DGRAM`](https://python-all.ru/3.6/library/socket.html#socket.SOCK_DGRAM). *protocol\_factory* должен быть вызываемым объектом, возвращающим экземпляр [протокола](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-protocol).

Этот метод является [корутиной](https://python-all.ru/3.6/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(transport, protocol)`.

Параметры, изменяющие способ создания соединения:

- *local\_addr*, если задан, представляет собой кортеж `(local_host, local_port)`, используемый для привязки сокета локально. *local\_host* и *local\_port* разрешаются с помощью [`getaddrinfo()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo).
- *remote\_addr*, если задан, представляет собой кортеж `(remote_host, remote_port)`, используемый для подключения сокета к удалённому адресу. *remote\_host* и *remote\_port* разрешаются с помощью [`getaddrinfo()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo).
- *family*, *proto*, *flags* – необязательные семейство адресов, протокол и флаги, передаваемые в [`getaddrinfo()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo) для разрешения *host*. Если заданы, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.6/library/socket.html#module-socket).
- *reuse\_port* сообщает ядру, что данная конечная точка может быть привязана к тому же порту, что и другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Этот параметр не поддерживается в Windows и некоторых UNIX. Если константа `SO_REUSEPORT` не определена, эта возможность не поддерживается.
- *allow\_broadcast* указывает ядру разрешить этой конечной точке отправлять сообщения на широковещательный адрес.
- *sock* может быть указан необязательно, чтобы использовать уже существующий, подключённый объект [`socket.socket`](https://python-all.ru/3.6/library/socket.html#socket.socket) для транспорта. Если указан, *local\_addr* и *remote\_addr* должны быть опущены (должны быть [`None`](https://python-all.ru/3.6/library/constants.html#None)).

В Windows с [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) этот метод не поддерживается.

См. примеры [протокол UDP-клиента эхо](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-udp-echo-client-protocol) и [протокол UDP-сервера эхо](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-udp-echo-server-protocol).

Изменено в версии 3.4.4: Добавлены параметры *family*, *proto*, *flags*, *reuse\_address*, *reuse\_port, \*allow\_broadcast* и *sock*.

Изменено в версии 3.6.10: Параметр *reuse\_address* больше не поддерживается по соображениям безопасности.

#### `coroutine AbstractEventLoop.create_unix_connection(protocol_factory, path, *, ssl=None, sock=None, server_hostname=None)`

Создание UNIX-соединения: семейство сокетов [`AF_UNIX`](https://python-all.ru/3.6/library/socket.html#socket.AF_UNIX), тип сокета [`SOCK_STREAM`](https://python-all.ru/3.6/library/socket.html#socket.SOCK_STREAM). Семейство сокетов [`AF_UNIX`](https://python-all.ru/3.6/library/socket.html#socket.AF_UNIX) используется для эффективного взаимодействия между процессами на одной машине.

Этот метод является [корутиной](https://python-all.ru/3.6/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(transport, protocol)`.

*path* – это имя сокета домена UNIX и требуется, если не указан параметр *sock*. Поддерживаются абстрактные UNIX-сокеты, пути [`str`](https://python-all.ru/3.6/library/stdtypes.html#str) и [`bytes`](https://python-all.ru/3.6/library/stdtypes.html#bytes).

О параметрах см. метод [`AbstractEventLoop.create_connection()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_connection).

Доступность: UNIX.

## 18.5.1.7. Создание слушающих соединений

#### `coroutine AbstractEventLoop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None)`

Создаёт TCP-сервер (тип сокета [`SOCK_STREAM`](https://python-all.ru/3.6/library/socket.html#socket.SOCK_STREAM)), привязанный к *host* и *port*.

Возвращает объект [`Server`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Server), его атрибут [`sockets`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Server.sockets) содержит созданные сокеты. Используйте метод [`Server.close()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Server.close) для остановки сервера: закрыть слушающие сокеты.

Параметры:

- Параметр *host* может быть строкой; в этом случае TCP-сервер привязывается к *host* и *port*. Параметр *host* также может быть последовательностью строк, и тогда TCP-сервер привязывается ко всем хостам из этой последовательности. Если *host* – пустая строка или `None`, подразумеваются все интерфейсы, и будет возвращён список из нескольких сокетов (скорее всего, один для IPv4 и один для IPv6).
- *family* можно установить в [`socket.AF_INET`](https://python-all.ru/3.6/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.6/library/socket.html#socket.AF_INET6), чтобы заставить сокет использовать IPv4 или IPv6. Если не установлено, значение будет определено из host (по умолчанию `socket.AF_UNSPEC`).
- *flags* – битовая маска для [`getaddrinfo()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo).
- *sock* можно указать, чтобы использовать уже существующий объект сокета. Если он указан, *host* и *port* следует опустить (они должны быть [`None`](https://python-all.ru/3.6/library/constants.html#None)).
- *backlog* – максимальное количество соединений в очереди, передаваемое в [`listen()`](https://python-all.ru/3.6/library/socket.html#socket.socket.listen) (по умолчанию 100).
- *ssl* можно установить в [`SSLContext`](https://python-all.ru/3.6/library/ssl.html#ssl.SSLContext), чтобы включить SSL для принятых соединений.
- *reuse\_address* указывает ядру повторно использовать локальный сокет в состоянии TIME\_WAIT, не дожидаясь истечения его естественного таймаута. Если не указано, автоматически устанавливается в `True` на UNIX.
- *reuse\_port* указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Эта опция не поддерживается в Windows.

Этот метод является [корутиной](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

Изменено в версии 3.5: На Windows с [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) теперь поддерживается SSL/TLS.

> **См. также**
>
> Функция [`start_server()`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.start_server) создаёт пару ([`StreamReader`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.StreamReader), [`StreamWriter`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.StreamWriter)) и вызывает колбэк с этой парой.

Изменено в версии 3.5.1: Параметр *host* теперь может быть последовательностью строк.

#### `coroutine AbstractEventLoop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None)`

Аналогично [`AbstractEventLoop.create_server()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server), но для семейства сокетов [`AF_UNIX`](https://python-all.ru/3.6/library/socket.html#socket.AF_UNIX).

Этот метод является [корутиной](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

Доступность: UNIX.

#### `coroutine BaseEventLoop.connect_accepted_socket(protocol_factory, sock, *, ssl=None)`

Обработать принятое соединение.

Это используется серверами, которые принимают соединения вне asyncio, но используют asyncio для их обработки.

Параметры:

- *sock* – это уже существующий объект сокета, возвращённый вызовом `accept`.
- *ssl* можно установить в [`SSLContext`](https://python-all.ru/3.6/library/ssl.html#ssl.SSLContext), чтобы включить SSL для принятых соединений.

Этот метод является [корутиной](https://python-all.ru/3.6/library/asyncio-task.html#coroutine). После завершения корутина возвращает пару `(transport, protocol)`.

Новое в версии 3.5.3.

## 18.5.1.8. Наблюдение за файловыми дескрипторами

На Windows с [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) поддерживаются только дескрипторы сокетов (например, файловые дескрипторы каналов не поддерживаются).

На Windows с [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) эти методы не поддерживаются.

#### `AbstractEventLoop.add_reader(fd, callback, *args)`

Начать наблюдение за файловым дескриптором на готовность к чтению и затем вызвать *колбэк* с указанными аргументами.

[Используйте functools.partial, чтобы передать именованные аргументы в колбэк](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-pass-keywords).

#### `AbstractEventLoop.remove_reader(fd)`

Прекратить наблюдение за файловым дескриптором на готовность к чтению.

#### `AbstractEventLoop.add_writer(fd, callback, *args)`

Начать наблюдение за файловым дескриптором на готовность к записи и затем вызвать *колбэк* с указанными аргументами.

[Используйте functools.partial, чтобы передать именованные аргументы в колбэк](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-pass-keywords).

#### `AbstractEventLoop.remove_writer(fd)`

Прекратить наблюдение за файловым дескриптором на готовность к записи.

Пример [наблюдения за файловым дескриптором на события чтения](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-watch-read-event) использует низкоуровневый метод [`AbstractEventLoop.add_reader()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_reader) для регистрации файлового дескриптора сокета.

## 18.5.1.9. Низкоуровневые операции с сокетами

#### `coroutine AbstractEventLoop.sock_recv(sock, nbytes)`

Получает данные из сокета. Аналогично блокирующему методу [`socket.socket.recv()`](https://python-all.ru/3.6/library/socket.html#socket.socket.recv).

Возвращаемое значение – объект bytes, представляющий полученные данные. Максимальный объём данных, который можно получить за один раз, задаётся параметром *nbytes*.

В [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий сокет *sock* должен быть неблокирующим.

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

#### `coroutine AbstractEventLoop.sock_sendall(sock, data)`

Отправляет данные в сокет. Аналогично блокирующему методу [`socket.socket.sendall()`](https://python-all.ru/3.6/library/socket.html#socket.socket.sendall).

Сокет должен быть подключён к удалённому сокету. Этот метод продолжает отправлять данные из *data*, пока либо не будут отправлены все данные, либо не произойдёт ошибка. В случае успеха возвращается `None`. При ошибке возникает исключение, и невозможно определить, сколько данных (если вообще какие-то) было успешно обработано принимающей стороной соединения.

В [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий сокет *sock* должен быть неблокирующим.

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

#### `coroutine AbstractEventLoop.sock_connect(sock, address)`

Подключается к удалённому сокету по адресу *address*. Аналогично блокирующему методу [`socket.socket.connect()`](https://python-all.ru/3.6/library/socket.html#socket.socket.connect).

В [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий сокет *sock* должен быть неблокирующим.

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

Изменено в версии 3.5.2: `address` больше не требует разрешения. `sock_connect` попытается проверить, разрешён ли уже *address*, вызвав [`socket.inet_pton()`](https://python-all.ru/3.6/library/socket.html#socket.inet_pton). Если нет, [`AbstractEventLoop.getaddrinfo()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo) будет использован для разрешения *address*.

> **См. также**
>
> [`AbstractEventLoop.create_connection()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_connection) и [`asyncio.open_connection()`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.open_connection).

#### `coroutine AbstractEventLoop.sock_accept(sock)`

Принимает соединение. Аналогично блокирующему [`socket.socket.accept()`](https://python-all.ru/3.6/library/socket.html#socket.socket.accept).

Сокет должен быть привязан к адресу и ожидать подключения. Возвращаемое значение – пара `(conn, address)`, где *conn* – это *новый* объект сокета, пригодный для отправки и получения данных по соединению, а *address* – адрес, привязанный к сокету на другом конце соединения.

Сокет *sock* должен быть неблокирующим.

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

> **См. также**
>
> [`AbstractEventLoop.create_server()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server) и [`start_server()`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.start_server).

## 18.5.1.10. Разрешение имени хоста

#### `coroutine AbstractEventLoop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)`

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine), аналогичная функции [`socket.getaddrinfo()`](https://python-all.ru/3.6/library/socket.html#socket.getaddrinfo), но неблокирующая.

#### `coroutine AbstractEventLoop.getnameinfo(sockaddr, flags=0)`

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine), аналогичная функции [`socket.getnameinfo()`](https://python-all.ru/3.6/library/socket.html#socket.getnameinfo), но неблокирующая.

## 18.5.1.11. Подключение каналов

В Windows с [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) эти методы не поддерживаются. Используйте [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) для поддержки каналов в Windows.

#### `coroutine AbstractEventLoop.connect_read_pipe(protocol_factory, pipe)`

Регистрирует канал чтения в цикле событий.

*protocol\_factory* должен создавать объект с интерфейсом [`Protocol`](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio.Protocol). *pipe* – это [объект, подобный файлу](https://python-all.ru/3.6/glossary.html#term-file-object). Возвращает пару `(transport, protocol)`, где *транспорт* поддерживает интерфейс [`ReadTransport`](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio.ReadTransport).

При [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий канал *pipe* переводится в неблокирующий режим.

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

#### `coroutine AbstractEventLoop.connect_write_pipe(protocol_factory, pipe)`

Регистрирует канал записи в цикле событий.

*protocol\_factory* должен создавать объект с интерфейсом `BaseProtocol`. *pipe* – это [объект, подобный файлу](https://python-all.ru/3.6/glossary.html#term-file-object). Возвращает пару `(transport, protocol)`, где *транспорт* поддерживает интерфейс [`WriteTransport`](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio.WriteTransport).

При [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий канал *pipe* переводится в неблокирующий режим.

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

> **См. также**
>
> Методы [`AbstractEventLoop.subprocess_exec()`](https://python-all.ru/3.6/library/asyncio-subprocess.html#asyncio.AbstractEventLoop.subprocess_exec) и [`AbstractEventLoop.subprocess_shell()`](https://python-all.ru/3.6/library/asyncio-subprocess.html#asyncio.AbstractEventLoop.subprocess_shell).

## 18.5.1.12. Сигналы UNIX

Доступно: только UNIX.

#### `AbstractEventLoop.add_signal_handler(signum, callback, *args)`

Добавляет обработчик сигнала.

Вызывает [`ValueError`](https://python-all.ru/3.6/library/exceptions.html#ValueError), если номер сигнала недопустим или его невозможно перехватить. Вызывает [`RuntimeError`](https://python-all.ru/3.6/library/exceptions.html#RuntimeError), если возникла проблема при установке обработчика.

[Используйте functools.partial для передачи именованных аргументов в колбэк](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-pass-keywords).

#### `AbstractEventLoop.remove_signal_handler(sig)`

Удаляет обработчик сигнала.

Возвращает `True`, если обработчик сигнала был удалён, и `False` в противном случае.

> **См. также**
>
> Модуль [`signal`](https://python-all.ru/3.6/library/signal.html#module-signal).

## 18.5.1.13. Исполнитель

Вызывает функцию в [`Executor`](https://python-all.ru/3.6/library/concurrent.futures.html#concurrent.futures.Executor) (пуле потоков или пуле процессов). По умолчанию цикл событий использует исполнитель с пулом потоков ([`ThreadPoolExecutor`](https://python-all.ru/3.6/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).

#### `coroutine AbstractEventLoop.run_in_executor(executor, func, *args)`

Планирует вызов функции *func* в указанном исполнителе.

Аргумент *исполнитель* должен быть экземпляром [`Executor`](https://python-all.ru/3.6/library/concurrent.futures.html#concurrent.futures.Executor) Исполнитель по умолчанию используется, если *исполнитель* равен `None`.

[Используйте functools.partial для передачи именованных аргументов в \*func\*](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-pass-keywords).

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

Изменено в версии 3.5.3: `BaseEventLoop.run_in_executor()` больше не настраивает `max_workers` создаваемого исполнителя пула потоков, оставляя настройку по умолчанию самому исполнителю пула потоков ([`ThreadPoolExecutor`](https://python-all.ru/3.6/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).

#### `AbstractEventLoop.set_default_executor(executor)`

Устанавливает исполнитель по умолчанию, используемый [`run_in_executor()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_in_executor).

## 18.5.1.14. API обработки ошибок

Позволяет настраивать обработку исключений в цикле событий.

#### `AbstractEventLoop.set_exception_handler(handler)`

Устанавливает *handler* в качестве нового обработчика исключений цикла событий.

Если *handler* равен `None`, будет установлен обработчик исключений по умолчанию.

Если *handler* – вызываемый объект, его сигнатура должна совпадать с `(loop, context)`, где `loop` будет ссылкой на активный цикл событий, `context` будет объектом `dict` (см. документацию [`call_exception_handler()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_exception_handler) для подробностей о контексте).

#### `AbstractEventLoop.get_exception_handler()`

Возвращает обработчик исключений или `None`, если используется стандартный.

Новое в версии 3.5.2.

#### `AbstractEventLoop.default_exception_handler(context)`

Обработчик исключений по умолчанию.

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

Параметр *context* имеет то же значение, что и в [`call_exception_handler()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_exception_handler).

#### `AbstractEventLoop.call_exception_handler(context)`

Вызывает обработчик исключений текущего цикла событий.

*context* – объект `dict`, содержащий следующие ключи (новые ключи могут быть добавлены позже):

- ‘message’: сообщение об ошибке;
- 'исключение' (необязательно): объект исключения;
- ‘future’ (необязательно): экземпляр [`asyncio.Future`](https://python-all.ru/3.6/library/asyncio-task.html#asyncio.Future);
- ‘handle’ (необязательно): экземпляр [`asyncio.Handle`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Handle);
- 'протокол' (необязательно): экземпляр [Protocol](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-protocol);
- 'транспорт' (необязательно): экземпляр [Transport](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-transport);
- ‘socket’ (необязательно): экземпляр [`socket.socket`](https://python-all.ru/3.6/library/socket.html#socket.socket).

> **Примечание**
>
> Примечание: этот метод не следует переопределять в подклассах циклов событий. Для любой пользовательской обработки исключений используйте метод [`set_exception_handler()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.set_exception_handler).

## 18.5.1.15. Режим отладки

#### `AbstractEventLoop.get_debug()`

Возвращает режим отладки ([`bool`](https://python-all.ru/3.6/library/functions.html#bool)) цикла событий.

Значение по умолчанию – `True`, если переменная окружения [`PYTHONASYNCIODEBUG`](https://python-all.ru/3.6/using/cmdline.html#envvar-PYTHONASYNCIODEBUG) имеет непустое строковое значение, и `False` в противном случае.

Новое в версии 3.4.2.

#### `AbstractEventLoop.set_debug(enabled: bool)`

Устанавливает режим отладки цикла событий.

Новое в версии 3.4.2.

> **См. также**
>
> [Режим отладки asyncio](https://python-all.ru/3.6/library/asyncio-dev.html#asyncio-debug-mode).

## 18.5.1.16. Сервер

#### `class asyncio.Server`

Сервер, прослушивающий сокеты.

Объект, создаваемый методом [`AbstractEventLoop.create_server()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server) и функцией [`start_server()`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.start_server). Не создавайте экземпляр класса напрямую.

#### `close()`

Прекращает обслуживание: закрывает слушающие сокеты и устанавливает атрибут [`sockets`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Server.sockets) в `None`.

Сокеты существующих входящих подключений клиентов остаются открытыми.

Сервер закрывается асинхронно, используйте [`wait_closed()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Server.wait_closed)\\nкорутину, чтобы дождаться закрытия сервера.

#### `coroutine wait_closed()`

Ожидайте завершения метода [`close()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.Server.close).

Этот метод – [корутина](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

#### `sockets`

Список объектов [`socket.socket`](https://python-all.ru/3.6/library/socket.html#socket.socket), которые прослушивает сервер, или `None`, если сервер закрыт.

## 18.5.1.17. Обработчик

#### `class asyncio.Handle`

Объект-обёртка колбэка, возвращаемый функциями [`AbstractEventLoop.call_soon()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon), [`AbstractEventLoop.call_soon_threadsafe()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon_threadsafe), [`AbstractEventLoop.call_later()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later) и [`AbstractEventLoop.call_at()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_at).

#### `cancel()`

Отменяет вызов. Если колбэк уже отменён или выполнен, этот метод ничего не делает.

## 18.5.1.18. Примеры циклов событий

### 18.5.1.18.1. Hello World с call\_soon()

Пример использования метода [`AbstractEventLoop.call_soon()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon) для планирования колбэка. Колбэк выводит `"Hello World"` и затем останавливает цикл событий:

```python
import asyncio

def hello_world(loop):
    print('Hello World')
    loop.stop()

loop = asyncio.get_event_loop()

# Запланировать вызов hello_world()
loop.call_soon(hello_world, loop)

# Блокирующий вызов прерван loop.stop()
loop.run_forever()
loop.close()
```

> **См. также**
>
> Пример [корутины Hello World](https://python-all.ru/3.6/library/asyncio-task.html#asyncio-hello-world-coroutine) использует [корутину](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

### 18.5.1.18.2. Отображение текущей даты с помощью call\_later()

Пример колбэка, который каждую секунду выводит текущую дату. Колбэк использует метод [`AbstractEventLoop.call_later()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later), чтобы перепланировать себя на 5 секунд, а затем останавливает цикл событий:

```python
import asyncio
import datetime

def display_date(end_time, loop):
    print(datetime.datetime.now())
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, display_date, end_time, loop)
    else:
        loop.stop()

loop = asyncio.get_event_loop()

# Запланировать первый вызов display_date()
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)

# Блокирующий вызов прерван loop.stop()
loop.run_forever()
loop.close()
```

> **См. также**
>
> Пример [корутины, отображающей текущую дату](https://python-all.ru/3.6/library/asyncio-task.html#asyncio-date-coroutine) использует [корутину](https://python-all.ru/3.6/library/asyncio-task.html#coroutine).

### 18.5.1.18.3. Отслеживать файловый дескриптор на события чтения

Ожидание, пока файловый дескриптор не получит некоторые данные, с помощью метода [`AbstractEventLoop.add_reader()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_reader), после чего цикл событий закрывается:

```python
import asyncio
try:
    from socket import socketpair
except ImportError:
    from asyncio.windows_utils import socketpair

# Создать пару связанных файловых дескрипторов
rsock, wsock = socketpair()
loop = asyncio.get_event_loop()

def reader():
    data = rsock.recv(100)
    print("Received:", data.decode())
    # Готово: отменить регистрацию файлового дескриптора
    loop.remove_reader(rsock)
    # Остановить цикл событий
    loop.stop()

# Зарегистрировать файловый дескриптор для события чтения
loop.add_reader(rsock, reader)

# Симулировать приём данных из сети
loop.call_soon(wsock.send, 'abc'.encode())

# Запустить цикл событий
loop.run_forever()

# Мы закончили, закрываем сокеты и цикл событий
rsock.close()
wsock.close()
loop.close()
```

> **См. также**
>
> Пример [регистрации открытого сокета для ожидания данных с помощью протокола](https://python-all.ru/3.6/library/asyncio-protocol.html#asyncio-register-socket) использует низкоуровневый протокол, созданный методом [`AbstractEventLoop.create_connection()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_connection).
>
> В примере [регистрации открытого сокета для ожидания данных с помощью потоков](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio-register-socket-streams) используются высокоуровневые потоки , созданные функцией [`open_connection()`](https://python-all.ru/3.6/library/asyncio-stream.html#asyncio.open_connection) в корутине.

### 18.5.1.18.4. Установить обработчики сигналов для SIGINT и SIGTERM

Зарегистрировать обработчики для сигналов `SIGINT` и `SIGTERM` с помощью метода [`AbstractEventLoop.add_signal_handler()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_signal_handler):

```python
import asyncio
import functools
import os
import signal

def ask_exit(signame):
    print("got signal %s: exit" % signame)
    loop.stop()

loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
    loop.add_signal_handler(getattr(signal, signame),
                            functools.partial(ask_exit, signame))

print("Event loop running forever, press Ctrl+C to interrupt.")
print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())
try:
    loop.run_forever()
finally:
    loop.close()
```

Этот пример работает только на UNIX.
