rust - 我是否需要在 mpsc 频道上调用 close,即使我同时删除了 Sender 和 Receiver?
问题描述
考虑以下示例:
use tokio::sync::mpsc;
#[tokio::main]
async fn main() {
let (mut sender, receiver) = mpsc::channel::<u32>(32);
sender.send(42).await.unwrap();
std::mem::drop(sender);
std::mem::drop(receiver);
}
在这里,我创建了一个mpsc
Sender
/Receiver
对,我sender
用来发送一个值,但我从未在receiver
. 然后,不调用close
,receiver
我同时删除sender
和receiver
。
Tokio 的mpsc 文档似乎指出,Receiver
不调用close
并使用所有值就删除 a 是不明智的,因为值可能会在通道中永远存在而不会被删除。我想知道这是否也适用于上面的例子。在那里,我删除了theReceiver
和 all (即唯一的)Sender
s。不知何故,我很难想象这会导致内存泄漏,但我想确保我正在做的事情是否安全。
解决方案
文档的重点是建议良好的做法。拥有不读取所有生成的项目的代码是可疑的。如果您需要停止行为,则应在发件人中实施。接收器不应该自行停止。
关闭通过关闭接收者来防止来自发送者的新消息来允许中间立场。比接收器可以读取直到没有消息,防止任何松动。
但是没有这个要求,如果你愿意,你不需要这样做。正如我们在这里看到的,drop 实现无论如何都会清理内存:
impl<T, S: Semaphore> Drop for Rx<T, S> {
fn drop(&mut self) {
use super::block::Read::Value;
self.close();
self.inner.rx_fields.with_mut(|rx_fields_ptr| {
let rx_fields = unsafe { &mut *rx_fields_ptr };
while let Some(Value(_)) = rx_fields.list.pop(&self.inner.tx) {
self.inner.semaphore.add_permit();
}
})
}
}
推荐阅读
- android - 当 popbackstack OnResume(), OnCreateView() 时,什么都没有被调用。但显示了前一个片段。想恢复fragment怎么办?
- ime - 我不知道为什么我不能得到 ImmGetCandidateList() func 的“汉字列表”
- c++ - 程序运行到一半就停止了?
- javascript - reCaptcha 未显示在我的单页网站上
- php - WordPress nav walker 分成三列
- ansible - Ansible 库存:替换问题
- android - Android Studio 的奇怪行为
- mysql - 通过时间戳进行 SQL 分组产生了意想不到的结果
- ssas - 尝试构建多维数据集并低于错误
- iis-8 - web.config 中的 IIS 重定向