Модуль mpsc
sync.Очередь «многие производители — один потребитель» для отправки значений между асинхронными задачами.
Этот модуль предоставляет два варианта канала: ограниченный и неограниченный. Ограниченный вариант имеет предел на число сообщений, которые может хранить канал. Если этот предел достигнут, попытка отправить ещё одно сообщение будет ждать, пока сообщение не будет получено из канала. Неограниченный канал имеет бесконечную ёмкость, поэтому метод send всегда завершается немедленно. Благодаря этому UnboundedSender можно использовать как в синхронном, так и в асинхронном коде.
Подобно каналам mpsc, предоставляемым std, функции создания канала возвращают отдельные дескрипторы для отправки и получения: Sender и Receiver для ограниченного канала, UnboundedSender и UnboundedReceiver для неограниченного канала. Если сообщений для чтения нет, текущая задача получит уведомление при отправке нового значения. Sender и UnboundedSender позволяют отправлять значения в канал. Если ограниченный канал заполнен, отправка отклоняется, а задача получит уведомление, когда появится дополнительная ёмкость. Иными словами, канал обеспечивает обратное давление.
Этот канал также подходит для сценария «один производитель — один потребитель». (Если вам нужно отправить только одно сообщение, используйте канал oneshot.)
Отключение
Когда все дескрипторы Sender удалены, отправлять значения в канал становится невозможно. Это считается событием завершения потока. После удаления всех отправителей и получения всех оставшихся буферизованных значений Receiver::recv возвращает None (а Receiver::poll_recv возвращает Poll::Ready(None)).
Если дескриптор Receiver удалён, сообщения больше нельзя прочитать из канала. В этом случае все дальнейшие попытки отправки завершатся ошибкой. Кроме того, все непрочитанные сообщения будут извлечены из канала и удалены.
Корректное завершение работы
При удалении Receiver в канале могут остаться необработанные сообщения. Обычно вместо этого желательно выполнить «корректное» завершение работы. Для этого получатель сначала вызывает close, запрещая отправку новых сообщений в канал. Затем получатель читает сообщения из канала до конца, после чего его можно удалить.
Обмен данными между синхронным и асинхронным кодом
При обмене данными между синхронным и асинхронным кодом следует учитывать два сценария:
Ограниченный канал: если вам нужен ограниченный канал, для обмена данными в обоих направлениях используйте ограниченный канал Tokio mpsc. Вместо асинхронных методов send или recv в синхронном коде нужно использовать методы blocking_send или blocking_recv.
Неограниченный канал: используйте тип канала, соответствующий месту нахождения получателя. Например, для отправки сообщения из асинхронного кода в синхронный используйте неограниченный канал стандартной библиотеки или crossbeam. Аналогично, для отправки сообщения из синхронного кода в асинхронный используйте неограниченный канал Tokio mpsc.
Обратите внимание: приведённые выше замечания относятся к каналу mpsc, но их можно обобщить и на другие типы каналов. В целом любой метод канала, не помеченный как асинхронный, можно вызывать где угодно, в том числе вне среды выполнения. Например, отправлять сообщение по каналу oneshot вне среды выполнения совершенно допустимо.
Несколько сред выполнения
Канал mpsc не зависит от среды выполнения. Его можно свободно перемещать между разными экземплярами среды выполнения Tokio или даже использовать в средах выполнения, отличных от Tokio.
При использовании в среде выполнения Tokio канал участвует в кооперативном планировании, чтобы избежать голодания. Эта возможность недоступна при использовании в средах выполнения, отличных от Tokio.
Исключение составляют методы, оканчивающиеся на _timeout: они зависят от среды выполнения, поскольку требуют доступа к таймеру Tokio. Подробнее об использовании каждого метода *_timeout см. в его документации.
Поведение при выделении памяти
Канал mpsc хранит элементы в блоках. Блоки организованы в связный список. При отправке новые элементы помещаются в блок в начале списка, а при получении извлекаются из блока в его конце. Блок может содержать 32 сообщения на 64-разрядной платформе и 16 сообщений на 32-разрядной. Это число не зависит от размера канала и сообщений. Каждый блок также хранит 4 значения размером с указатель для служебных целей (поэтому на 64-разрядной машине накладные расходы составляют 1 байт на сообщение).
Когда все значения из блока получены, он становится пустым. Затем блок освобождается, если только первый блок канала (в который помещаются вновь отправленные элементы) не лишён следующего блока. В этом случае пустой блок повторно используется в качестве следующего.
Модули
- error
- Типы ошибок канала.
Структуры
- Owned
Permit - Владеющее разрешение на отправку одного значения в канал.
- Permit
- Разрешение на отправку одного значения в канал.
- Permit
Iterator IteratorизPermit, который можно использовать для резервированияnмест в канале.- Receiver
- Получает значения из связанного
Sender. - Sender
- Отправляет значения в связанный
Receiver. - Unbounded
Receiver - Получает значения из связанного
UnboundedSender. - Unbounded
Sender - Отправляет значения в связанный
UnboundedReceiver. - Weak
Sender - Отправитель, который не препятствует закрытию канала.
- Weak
Unbounded Sender - Неограниченный отправитель, который не препятствует закрытию канала.
Функции
- channel
- Создаёт ограниченный канал mpsc для обмена данными между асинхронными задачами с обратным давлением.
- unbounded_
channel - Создаёт неограниченный канал mpsc для обмена данными между асинхронными задачами без обратного давления.
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/sync/mpsc/index.html