我想实现一个简单的服务器,由我项目的3个不同模块使用 这些模块将数据发送到服务器,服务器将其保存到文件中,并在这些模块完成工作时合并这些信息。 所有这些信息都有时间戳(浮点数)和标签(浮点数或字符串)。
这是我保存这些信息的数据结构:
pub struct Data {
file_name: String,
logs: Vec<(f32, String)>,
measures: Vec<(f32, f32)>,
statements: Vec<(f32, String)>,
}
我使用socket
与服务器进行交互。
我还使用Arc
来实现Data
结构,并使其可以为每个模块共享。
因此,当我处理客户端时,我验证模块发送的消息是否正确,如果是,我调用一个新函数来处理并将消息保存在良好的数据结构字段中logs
,{{ 1}}或measures
)。
statements
我在// Current ip address
let ip_addr: &str = &format!("{}:{}",
&ip,
port);
// Bind the current IP address
let listener = match TcpListener::bind(ip_addr) {
Ok(listener) => listener,
Err(error) => panic!("Canno't bind {}, due to error {}",
ip_addr,
error),
};
let global_data_struct = Data::new(DEFAULT_FILE.to_string());
let global_data_struct_shared = Arc::new(global_data_struct);
// Get and process streams
for stream in listener.incoming() {
let mut global_data_struct_shared_clone = global_data_struct_shared.clone();
thread::spawn(move || {
// Borrow stream
let stream = stream;
match stream {
// Get the stream value
Ok(mut stream_v) => {
let current_ip = stream_v.peer_addr().unwrap().ip();
let current_port = stream_v.peer_addr().unwrap().port();
println!("Connected with peer {}:{}", current_ip, current_port);
// PROBLEM IN handle_client!
// A get_mut from global_data_struct_shared_clone
// returns to me None, not a value - so I
// can't access to global_data_struct_shared_clone
// fields :'(
handle_client(&mut stream_v, &mut global_data_struct_shared_clone);
},
Err(_) => error!("Canno't decode stream"),
}
});
}
// Stop listening
drop(listener);
中获取可变引用以处理handle_client
中的字段时遇到一些问题,因为global_data_struct_shared_clone
返回给我Arc::get_mut(global_data_struct_shared_clone)
- 由于{{1}每个传入的请求。
有人可以帮我正确管理这3个模块之间的这种结构吗?
答案 0 :(得分:0)
Rust的见解是通过强制执行别名XOR可变性来实现内存安全。
实施这一单一原则可以防止整个类别的错误:指针/迭代器失效(这是目标)以及数据竞争。
Rust会尽可能地在编译时尝试强制执行此原则;但是,如果用户通过使用专用类型/方法选择,它也可以在运行时强制执行它。
Arc::get_mut
就是这样一种方法。 Arc
(原子参考计数指针)专门用于在多个所有者之间共享引用,这意味着别名,因此默认情况下不允许可变性; Arc::get_mut
将执行运行时检查:如果指针实际上不是别名(计数为1),则它允许可变性。
但是,正如您所知,这不适合您的情况,因为Arc
在该时间点存在别名。
所以你需要转向其他类型。
最简单的解决方案是Arc<Mutex<...>>
,Arc
允许共享,Mutex
允许受控制的可变性,您可以与Mutex
强制执行的运行时控制可变性共享。< / p>
这是粗粒度的,但可能就足够了。
更复杂的方法可以使用RwLock
(读者 - 写作者锁定),更细粒度的Mutex
甚至原子;但我会建议从一个Mutex
开始,看看它是怎么回事,你必须在跑步前走路。