展开描述
一次性 channel 用于在异步任务之间发送单个消息。channel 函数用于创建组成 channel 的 Sender 和 Receiver 句柄对。
Sender 句柄由生产者用于发送值。Receiver 句柄由消费者用于接收值。
每个句柄可以用于不同的任务。
由于 send 方法不是 async 的,因此可以在任何地方使用。这包括在两个运行时之间发送,以及在非异步代码中使用。
如果在已发送但尚未接收消息之前 Receiver 已关闭,则该消息将保留在 channel 中,直到 receiver 被 drop,此时消息将立即被 drop。
§示例
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 在未发送的情况下被 drop,则 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 channel,请在 channel 前面添加 &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
Oneshoterror types.
结构体§
函数§
- channel
- Creates a new one-shot channel for sending single values across asynchronous tasks.