高性能的两个结构之间的循环引用

时间:2019-07-09 05:18:30

标签: rust cyclic-reference

我有两个结构NodeCommunicatorNode包含“业务逻辑”,而Communicator包含用于发送和接收UDP消息的方法。 Node在要发送消息时需要在Communicator上调用方法,而Communicator在收到UDP消息时需要在Node上调用方法。如果它们是相同的结构,则完全没有问题。但我想将它们分开,因为它们显然有不同的责任。将所有内容都放在一个结构中将变得难以管理。我的代码如下:

fn main() {
    use std::sync::{Arc, Mutex, Condvar, Weak};
    use std::thread;


    pub struct Node {
        communicator: Option<Arc<Communicator>>
    }

    impl Node {
        pub fn new() -> Node {
            Node {
                communicator: None
            }
        }

        pub fn set_communicator(&mut self, communicator: Arc<Communicator>) {
            self.communicator = Some(communicator);
        }
    }

    pub struct Communicator {
        node: Option<Weak<Node>>
    }

    impl Communicator {
        pub fn new() -> Communicator {
            Communicator {
                node: None
            }
        }

        pub fn set_node(&mut self, node: Weak<Node>) {
            self.node = Some(node);
        }
    }



    let mut my_node = Arc::new(Node::new());
    let mut my_communicator = Arc::new(Communicator::new());

    Arc::get_mut(&mut my_node).unwrap().set_communicator(Arc::clone(&my_communicator));

    //Arc::get_mut(&mut my_communicator).unwrap().set_node(Arc::downgrade(&my_node));
}

如我所预料的,如果我取消最后两行的注释,我的代码将崩溃。但这是我想要实现的目标。

我看到几个选择:

  • 使用MutexRwLock获得内部可变性。但这会降低性能。
  • 使用CellRefCell。但是它们不是线程安全的。
  • 使用AtomicCell中的crossbeam。看起来是迄今为止最好的选择。但是性能呢?
  • 使用unsafe。但是哪里?以及如何unsafe来确保代码保持内存安全?

理论上,我可以将Communicator分为SenderReceiver,这样就不会有循环引用。但是对于我的程序,我知道将来会有类似的情况,这将是不可能的。

由于代码结构的原因,由于结构我将结构一分为二,并且没有获得任何新功能,因此应该有一种无需支付Mutex这样的性能损失的方法。

0 个答案:

没有答案
相关问题