Модуль oneshot
sync.Одноразовый канал используется для отправки одного сообщения между асинхронными задачами. Функция channel используется для создания пары дескрипторов Sender и Receiver, образующих канал.
Дескриптор Sender используется отправителем для отправки значения. Дескриптор Receiver используется получателем для получения значения.
Каждый дескриптор можно использовать в отдельной задаче.
Поскольку метод send не является асинхронным, его можно использовать где угодно. В том числе для отправки данных между двумя средами выполнения и из неасинхронного кода.
Если Receiver закрывается до получения уже отправленного сообщения, сообщение останется в канале, пока получатель не будет удален; в этот момент сообщение будет немедленно удалено.
Примеры
use tokio::sync::oneshot;
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}Если отправитель будет уничтожен, не отправив сообщение, получение завершится ошибкой error::RecvError:
use tokio::sync::oneshot;
let (tx, rx) = oneshot::channel::<u32>();
tokio::spawn(async move {
drop(tx);
});
match rx.await {
Ok(_) => panic!("This doesn't happen"),
Err(_) => println!("the sender dropped"),
}Чтобы использовать канал oneshot в цикле tokio::select!, добавьте &mut перед каналом.
use tokio::sync::oneshot;
use tokio::time::{interval, sleep, Duration};
let (send, mut recv) = oneshot::channel();
let mut interval = interval(Duration::from_millis(100));
tokio::spawn(async move {
sleep(Duration::from_secs(1)).await;
send.send("shut down").unwrap();
});
loop {
tokio::select! {
_ = interval.tick() => println!("Another 100ms"),
msg = &mut recv => {
println!("Got message: {}", msg.unwrap());
break;
}
}
}Чтобы использовать Sender из деструктора, поместите его в Option и вызовите Option::take.
use tokio::sync::oneshot;
struct SendOnDrop {
sender: Option<oneshot::Sender<&'static str>>,
}
impl Drop for SendOnDrop {
fn drop(&mut self) {
if let Some(sender) = self.sender.take() {
// Using `let _ =` to ignore send errors.
let _ = sender.send("I got dropped!");
}
}
}
let (send, recv) = oneshot::channel();
let send_on_drop = SendOnDrop { sender: Some(send) };
drop(send_on_drop);
assert_eq!(recv.await, Ok("I got dropped!"));Модули
- error
-
Oneshotтипы ошибок.
Структуры
- Receiver
- Получает значение от связанного
Sender. - Sender
- Отправляет значение связанному
Receiver.
Функции
- channel
- Создает новый одноразовый канал для отправки отдельных значений между асинхронными задачами.
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/sync/oneshot/index.html