Arc< Vec< >>内元件的 rust eclipse 寿命

ecfdbz9o  于 5个月前  发布在  Eclipse
关注(0)|答案(1)|浏览(42)

我来自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();
}

字符串

ukdjmx9f

ukdjmx9f1#

我在这里使用Arc<Vec<User>>来安全地在线程之间共享用户数据,而不克隆整个向量;我没有传递整个用户对象,而是将索引Vec<usize>的向量传递给工作线程。这种方法显著降低了内存开销。
试试here

use std::sync::Arc;
use std::sync::mpsc::channel;
use std::thread;

#[derive(Debug)]
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);

    // Specify the type of messages for the work channel
    let (tx_work, rx_work): (std::sync::mpsc::Sender<Vec<usize>>, std::sync::mpsc::Receiver<Vec<usize>>) = channel();
    let (tx_result, rx_result) = channel();

    let arc_my_vec_clone = Arc::clone(&arc_my_vec);
    let t = thread::spawn(move || {
        while let Ok(indices) = rx_work.recv() {
            let underage_indices: Vec<usize> = indices
                .into_iter()
                .filter(|&i| arc_my_vec_clone[i].age < 18)
                .collect();

            tx_result.send(underage_indices).unwrap();
        }
    });

    // Send the indices of the vector to the worker thread
    let indices: Vec<usize> = (0..arc_my_vec.len()).collect();
    tx_work.send(indices).unwrap();

    // Receive the result from the worker thread
    let underage_indices = rx_result.recv().unwrap();
    let underage_users: Vec<&User> = underage_indices
        .iter()
        .map(|&i| &arc_my_vec[i])
        .collect();

    dbg!(underage_users);

    t.join().unwrap();
}

字符串

相关问题