展开描述
一个多生产者、多消费者的 channel,仅保留最近一次发送的值。
此通道用于从代码库中的多个位置监视值的更改, 例如,配置值的更改。
§Usage
channel 返回一个
Sender /
Receiver
对。它们是通道的
生产者和消费者两半。
通道创建时
具有一个初始值。
每个 Receiver 独立跟踪
其调用者最后看到的值。
要访问通道中存储的当前值
并将其标记为已被给定
Receiver 视为已读,
请使用 Receiver::borrow_and_update()。
要在不将其标记为已读的情况下访问当前值,
请使用
Receiver::borrow()。
(如果该值已标记为已读,
Receiver::borrow() 等同于
Receiver::borrow_and_update()。)
有关何时使用这些方法的更多信息, 请参阅 此处。
§变更通知
Receiver 半提供了
一个异步的
changed 方法。
当通过 Sender 半
发送新的未见过的值时,
此方法就绪。
Receiver::changed()returns:Ok(())on receiving a new value.Err(RecvError)if the channel has been closed AND the current value is seen.
- If the current value is unseen when calling
changed, thenchangedwill return immediately. If the current value is seen, then it will sleep until either a new message is sent via theSenderhalf, or theSenderis dropped. - On completion, the
changedmethod marks the new value as seen. - At creation, the initial value is considered seen. In other words,
Receiver::changed()will not return until a subsequent value is sent. - New
Receiverinstances can be created withSender::subscribe(). The current value at the time theReceiveris created is considered seen.
§changed versus has_changed
Receiver 半提供了
两种用于检查通道变化的方法,
has_changed 和
changed。
-
has_changed是一个同步方法, 用于检查当前值是否已读, 并返回一个布尔值。 此方法不会将该值 标记为已读。 -
changed是一个异步方法, 一旦通道中存在未读过的值, 它就会返回。 此方法确实会将该值标记为已读。
请注意,这两种方法在返回错误时存在两个行为差异。
has_changederrors if and only if the channel is closed.changederrors if the channel has been closed AND the current value is seen.
请参见下面的示例,该示例展示了这些方法具有不同的可失败性。
§borrow_and_update versus borrow
如果 receiver 打算在循环中
等待来自
changed 的通知,
则应优先使用
Receiver::borrow_and_update()
而不是
Receiver::borrow()。
这避免了 changed 就绪
与读取值之间
可能发生的竞态。
(如果使用
Receiver::borrow(),
循环可能会使用相同的值运行两次。)
如果 receiver 仅对当前值感兴趣,
而不打算等待更改,
则可以使用
Receiver::borrow()。
使用 borrow
可能更方便,
因为它是 &self
方法——borrow_and_update
需要 &mut self。
§示例
以下示例打印 hello! world! 。
use tokio::sync::watch;
use tokio::time::{Duration, sleep};
let (tx, mut rx) = watch::channel("hello");
tokio::spawn(async move {
// Use the equivalent of a "do-while" loop so the initial value is
// processed before awaiting the `changed()` future.
loop {
println!("{}! ", *rx.borrow_and_update());
if rx.changed().await.is_err() {
break;
}
}
});
sleep(Duration::from_millis(100)).await;
tx.send("world")?;关于 changed 与
has_changed 在失败性方面的差异。
use tokio::sync::watch;
let (tx, mut rx) = watch::channel("hello");
tx.send("goodbye").unwrap();
drop(tx);
// `has_changed` does not mark the value as seen and errors
// since the channel is closed.
assert!(rx.has_changed().is_err());
// `changed` returns Ok since the value is not already marked as seen
// even if the channel is closed.
assert!(rx.changed().await.is_ok());
// The `changed` call above marks the value as seen.
// The next `changed` call now returns an error as the channel is closed
// AND the current value is seen.
assert!(rx.changed().await.is_err());§关闭(closing)
Sender::is_closed 和
Sender::closed
允许生产者检测
何时所有 Receiver
句柄都已被丢弃。
这表明对正在生成的值不再有兴趣,
可以停止工作。
在所有 sender 和 receiver 都被丢弃之前,channel 中的值不会被释放。
§Thread safety
Sender 和
Receiver 都是线程安全的。
它们可以移动到其他线程,
并可在并发环境中使用。
Receiver 句柄的克隆
可以移动到单独的线程,
也可以并发使用。
模块§
- error
- Watch 错误类型。
结构体§
函数§
- channel
- 创建一个新的 watch channel,返回"发送"和"接收"句柄。