展开描述
一次性通道用于在异步任务之间发送单个消息。
channel 函数用于创建
构成通道的 Sender 和 Receiver 句柄对。
Sender 句柄由生产者用于发送值。
Receiver 句柄由消费者用于接收值。
每个 handle 可以在不同的任务上使用。
由于 send 方法不是 async 的,
因此它可以在任何地方使用。
这包括在两个运行时之间发送,
以及从非异步代码使用它。
如果 Receiver 在接收一条已发送的消息之前已关闭,
则该消息将保留在通道中,
直到 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"),
}如果 sender 在未发送的情况下被丢弃,
receiver 将失败,
并出现
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"),
}要在 tokio::select! 循环中
使用 oneshot 通道,
请在通道前添加 &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错误类型。
结构体§
函数§
- channel
- 创建一个新的 one-shot channel,用于在异步任务之间发送单个值。