跳到主要内容

Module oneshot

搜索

Module oneshot 

Source
展开描述

一次性通道用于在异步任务之间发送单个消息。 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 错误类型。

结构体§

Receiver
从关联的 Sender 接收一个值。
Sender
向关联的 Receiver 发送一个值。

函数§

channel
创建一个新的 one-shot channel,用于在异步任务之间发送单个值。