我来自Golang背景,我正在Rust中做一个项目,它有以下设置:
我有一个基于2个通道的标准生产者/消费者设置:“工作通道”和“结果通道”。
生产者线程将工作发送到工作通道,并从结果通道接收结果。
使用者线程从工作通道接收工作,并将结果发送到结果通道。
我为Rust Playground中的问题创建了一个最小可重现的示例(同样粘贴在下面)。[注意:我知道这是解决这个特定问题的一种愚蠢的方法;在现实世界的问题中,我有一个向量作为输入,我使用一些元素作为哈希图的键,该哈希图返回包含对元素进行计算的结果]
我遇到的问题是,我想在输出向量中引用输入向量中的元素。
在MRE中,我有一个Vec<User>
作为输入,一个过滤后的Vec<User>
作为输出。理想情况下,我希望有一个Vec<&User>
作为输出,只是引用输入元素**,这样我就不必克隆它们**(underage.push(el.clone());
)。
我相信我明白是什么导致了这个问题,但我能想到的唯一解决方案是传递Arc<Vec<Arc<User>>
作为输入,这看起来很糟糕。
有没有一种方法可以返回Arc<Vec<&User>>
,将vector中元素的引用的生命周期与vector的生命周期连接起来?
谢谢你,谢谢
use std::sync::Arc;
use std::sync::mpsc::channel;
use std::thread;
#[derive(Debug, Clone)]
struct User {
age: u32,
}
fn main() {
let my_vec: Vec<User> = vec!(
User{age: 10},
User{age: 20},
User{age: 15},
User{age: 18},
);
let arc_my_vec = Arc::new(my_vec);
// this is a thread that listens for work on a rx_work channel
// and puts the result of the work on a tx_result channel
let (tx_work, rx_work) = channel();
let (tx_result, rx_result) = channel();
let t = thread::spawn(move || {
loop {
let users: Arc<Vec<User>> = rx_work.recv().unwrap();
let mut underage = vec![];
for el in users.iter() {
if el.age < 18 {
underage.push(el.clone());
}
}
tx_result.send(underage).unwrap();
}
});
let this_vec = Arc::clone(&arc_my_vec);
// put work on the channel that's followed by the thread
tx_work.send(this_vec).unwrap();
// receive the result from the thread work
let underage = rx_result.recv().unwrap();
dbg!(underage);
t.join().unwrap();
}
字符串
1条答案
按热度按时间ukdjmx9f1#
我在这里使用
Arc<Vec<User>>
来安全地在线程之间共享用户数据,而不克隆整个向量;我没有传递整个用户对象,而是将索引Vec<usize>
的向量传递给工作线程。这种方法显著降低了内存开销。试试here:
字符串