首页 > 解决方案 > 我是否需要在 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. 然后,调用closereceiver我同时删除senderreceiver

Tokio 的mpsc 文档似乎指出,Receiver不调用close并使用所有值就删除 a 是不明智的,因为值可能会在通道中永远存在而不会被删除。我想知道这是否也适用于上面的例子。在那里,我删除theReceiver和 all (即唯一的)Senders。不知何故,我很难想象这会导致内存泄漏,但我想确保我正在做的事情是否安全。

标签: rustrust-tokio

解决方案


文档的重点是建议良好的做法。拥有不读取所有生成的项目的代码是可疑的。如果您需要停止行为,则应在发件人中实施。接收器不应该自行停止。

关闭通过关闭接收者来防止来自发送者的新消息来允许中间立场。比接收器可以读取直到没有消息,防止任何松动。

但是没有这个要求,如果你愿意,你不需要这样做。正如我们在这里看到的,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();
            }
        })
    }
}

推荐阅读