【发布时间】:2019-04-02 09:16:10
【问题描述】:
我正在尝试编写一个简单的 tcp 服务器来读取和广播消息。
我正在使用 Tokio,但我认为这更像是一个通用的 Rust 问题。
我有一个共享状态的 Arc:let state = Arc::new(Mutex::new(Shared::new(server_tx)));
稍后我想生成 2 个线程,它们将使用对该状态的引用:
let server = listener.incoming().for_each(move |socket| {
// error[E0382]: capture of moved value: `state`
process(socket, state.clone());
Ok(())
}).map_err(|err| {
println!("accept error = {:?}", err);
});
let receive_sensor_messages = sensors_rx.for_each(move |line| {
println!("Received sensor message, broadcasting: {:?}", line);
// error[E0597]: borrowed value does not live long enough
// error[E0507]: cannot move out of borrowed content
for (_, tx) in state.clone().lock().unwrap().clients {
tx.unbounded_send(line.clone()).unwrap();
}
Ok(())
}).map_err(|err| {
println!("line reading error = {:?}", err);
});
据我所知,它试图告诉我的是state 在第一个闭包listener.incoming().for_each(move |socket| { 中被借用,所以当我尝试在sensors_rx.for_each(move |line| { 中再次这样做时,它说这是不可能的。
我的问题是如何解决? Arc 不是应该解决线程间共享变量的问题吗?
我尝试了clone 的不同组合(在闭包之外进行克隆,然后在内部再次进行clone),但没有一个有效。
干杯!
【问题讨论】:
-
你能尝试提供一个 MCVE 而不是一个成熟的程序吗?
-
“无法移出借用内容”的发生是因为
for循环消耗了它的参数(例如,参见 Looping through a RefCell wrapped Vec with Rust)。将该行更改为for (_, tx) in &state.lock().unwrap().clients会将您的问题减少到Arc问题。
标签: rust