You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tokio Watch Channel中克隆接收者与订阅发送者的区别是什么?

Tokio Watch Channel:sender.subscribe() 与 receiver.clone() 的差异

先看你给出的代码场景:

let (sender, mut receiver) = watch::channel(1);

let receiver_2 = sender.subscribe();
let receiver_3 = receiver.clone();

二者看似功能相近,但有两个容易忽略的关键差异:

1. 初始接收状态完全不同

每个Watch接收者都会维护自己的「是否已确认最新值」的状态:

  • 用sender.subscribe()创建的receiver_2,是一个全新的接收者,它初始状态是未确认当前最新值。也就是说,你直接调用receiver_2.changed().await会立即返回Ok(()),调用recv()也能直接拿到当前sender持有的最新值(这里就是初始化的1)。
  • 而receiver.clone()出来的receiver_3,会完全继承原receiver的状态。如果原receiver已经调用过recv()或者changed()确认过最新值,那么receiver_3也会处于「已确认」状态,此时调用changed().await会阻塞,直到sender发送新的数值。

举个实际代码例子就能看明白:

let (sender, mut receiver) = watch::channel(1);

// 让原receiver确认读取初始值
let _ = receiver.recv().await;

let receiver_2 = sender.subscribe();
let receiver_3 = receiver.clone();

// receiver_2的changed()会立即返回,因为它还没确认过初始值
assert!(receiver_2.changed().await.is_ok());
// receiver_3的changed()会阻塞,因为它继承了原receiver的已确认状态
// 如果此时sender.send(2).await.unwrap(),才会触发它返回

2. 创建时的依赖对象不同

  • sender.subscribe()必须通过发送者对象调用,依赖sender的当前可用性(调用时需要&Sender),但创建完成后,receiver_2的存活和sender是否被drop无关,只要channel内部状态还在(有其他发送者或接收者存活),它就能正常工作。
  • receiver.clone()只需要原接收者对象存在即可调用,和sender完全无关,哪怕sender已经被drop,只要原receiver还活着,就能克隆出可用的新接收者。

内容的提问来源于stack exchange,提问作者Pedro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:57:27