我正在与tokio
和hyper
一起产生多个任务。
// Defining the task
let task = self.some_future_using
.map(move |resp| println!("OK: {}", resp))
.map_err(move |e| println!("Error: {}",e));
// Spawning the task
tokio::spawn(task);
我不想简单地记录结果,而是想通过有限的tokio通道发送结果。
// Defines the channel
let (tx, rx) = mpsc::channel(10);
// Defining the task
let task = self.some_future_using
.map(|resp| /* Send Ok(resp) to tx */ )
.map_err(|e| /* Send Err(e) to tx */);
// Spawning the task
tokio::spawn(task);
由于两个闭包都可能超出了定义tx
的范围,因此我们需要为两个闭包克隆并移动tx
:
// Defines the channel
let (tx, rx) = mpsc::channel(10);
let mut tx_ok = tx.clone();
let mut tx_err = tx.clone();
// Defining the task
let task = self.some_future_using
.map(move |resp| tx_ok.try_send(Ok(())).unwrap() )
.map_err(move |e| tx_err.try_send(Ok(())).unwrap() );
// Spawning the task
tokio::spawn(task);
如果使用组合器(map
,and_then
等)添加了更多逻辑,则每个闭包都需要使用自己tx
的克隆版本才能使用它。
克隆是唯一的解决方案吗?我们能在不为使用该声明的每个闭包克隆通道发送者的情况下实现相同的功能吗?
答案 0 :(得分:0)
在不为使用它的每个声明的闭包克隆通道发送者的情况下,我们能否实现相同的目标?
不。这是共享Sender
的方式,而且没有另一种安全的方法。
通道通过将共享资源包装在Arc
中来管理共享资源,因此可以在线程之间安全地共享它们。 Sender
的clone方法涉及一些逻辑,但是最终它是关于克隆那些Arc
的-这就是Arc
的共享方式。
克隆Arc
很便宜,除非您要紧密地克隆它们,否则不必担心。克隆之后,Arc
的开销很小-每个克隆本质上都是一个指针。