rust - 两个高性能结构之间的循环引用
问题描述
我有两个结构Node
和Communicator
. Node
包含“业务逻辑”,同时Communicator
包含发送和接收 UDP 消息的方法。当它想要发送消息时Node
需要调用方法,当它接收到UDP消息时需要调用方法。如果它们是相同的结构,则完全没有问题。但我想将它们分开,因为它们显然有不同的职责。将所有内容都放在一个结构中将变得难以管理。我的代码如下所示:Communicator
Communicator
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));
}
如我所料,如果我取消注释最后两行,我的代码就会崩溃。但这是我想要实现的目标。
我看到了几个选项:
- 使用
Mutex
或RwLock
来获得内部可变性。但这会导致性能损失。 - 使用
Cell
或RefCell
。但它们不是线程安全的。 - 使用
AtomicCell
从crossbeam
. 看起来是迄今为止最好的选择。但是性能呢? - 使用
unsafe
. 但是哪里?以及如何确保代码保持内存安全unsafe
?
理论上我可以分成Communicator
aSender
和 a Receiver
,这样就不会有循环引用。但是对于我的程序,我知道我将来会遇到类似的情况,这是不可能的。
似乎由于我只是将一个结构分成两部分,出于代码结构的原因,并且没有获得新功能,所以应该有一种方法可以做到这一点,而不必支付任何性能损失Mutex
。
解决方案
推荐阅读
- sql - 无法在十进制列 SQL 中插入 int 值
- c++ - 是否需要重复调用带有右值引用的移动?
- swift - 如何打印/转储 NSObject?
- powerbi - Power BI 多项测量
- c# - ASP.NET Core Webb API 中的多个 HttpPost 方法
- javascript - 交换样式表 OnClick 演示页面
- javascript - 为什么外部变量在有条件的情况下不可用
- javascript - 如何将动态导入用于 redux 的“操作”以优化包大小
- python - 转换 for 循环以在 python 中应用函数以减少运行时间
- azure - Azure Application Insights 多次以相同的时间戳显示相同的事件