首页 > 解决方案 > Rust 如何获取 Arc 的内容

问题描述

我有一个包含TcpStream-TcpStream不保证存在的类 - 所以我最初使用Option但发现它Arc使用线程安全 - 并且由于我正在运行异步任务 - 这可能会导致一些线程问题。所以我结束了我的Arc<TcpStream>但在获取数据时遇到问题......

#[derive(Debug, Clone)]
enum ConnectionError {
    ConnectError(usize),
    SendError(usize),
}

#[derive(Debug, Clone)]
struct Connection {
    stream: Arc<TcpStream>,
    loc: usize,
}

impl Connection {
    async fn connect(loc:usize) -> Result<Connection, ConnectionError> {
        println!("Connecting");
        
        let stream = TcpStream::connect("3.77.107.247:86").await.map_err(|_| ConnectionError::ConnectError(loc))?;
        //stream.write_all(b"Hello World\n").await;

        Ok( Connection2 {
            stream: Arc::new(stream),
            loc: loc,
            }
        )
    }
    async fn Send(mut connection: Connection, string: String) -> Result<Connection2, ConnectionError> {
        println!("Count: {},", Arc::weak_count(&connection.stream));
        if let Some(x) = Arc::get_mut(&mut connection.stream) {
            x.write_all(b"HELLO").await.map_err(|_| ConnectionError::SendError(connection.loc))?;
        }
        else {
            println!("Unable to send message");
        }
        Ok( connection )
    }
}

我总是得到一个意想不到的输出:

无法发送消息线程“tokio-runtime-worker”在“调用值”时出现恐慌Option::unwrap()Nonesrc\main.rs:292:58 注意:使用RUST_BACKTRACE=1环境变量运行以显示回溯

这向我表明我的Arcget_mut 为空......

我已经打印出Weak count如图所示的内容,但输出为 0。

有什么指导吗?

标签: rustrust-tokio

解决方案


我有一个包含 TcpStream 的类 - 不能保证 TcpStream 存在 - 所以我最初使用 Option 但发现 Arc 使用线程安全 - 因为我正在运行异步任务 - 这可能会导致一些线程问题. 所以我结束了我的 Arc,但在获取数据时遇到了问题......

那是......可能完全是错误的解决方案?而且这两者甚至不能互换,哪里是

我有一个包含 TcpStream 的类 - 不能保证 TcpStream 存在

没了?Arc 不能做到这一点,它总是包含一些东西。

Option是线程安全的,一次只能存在于一个线程中。Arc是线程安全的,可以在线程之间共享。按照您的设计方式,您可以让多个Connection不同线程共享相同的底层 tcp 流,这听起来是个糟糕的主意。

此外,Arc不能直接变异(除非它特别具有 1 的强计数,这显然不是这里的情况),相反,您需要使用某种线程安全的“内部可变性”容器,它可以从不可变的,通常是 aMutexRWLock.

在这里,我看不到 theArc或 the 的意义Option

  • TcpStream直接在多个之间共享一个Connection听起来是个坏主意,某种池化或多路复用可能没问题,但我想要非常明确和有意的支持,而不仅仅是在管道中发送垃圾信息并希望它在另一端出现可接受的状态,交错的消息听起来像是灾难的秘诀。

  • Arc不能为空,所以

    我有一个包含 TcpStream 的类 - 不能保证 TcpStream 存在

    Option 的理由是没有意义的。


推荐阅读