【问题标题】:Is there a succinct way to spawn new threads with copies of existing data?是否有一种简洁的方法可以使用现有数据的副本生成新线程?
【发布时间】:2018-05-17 14:21:44
【问题描述】:

我正在尝试生成几个新线程,每个线程都有自己的某些状态的副本。我想要的是这样的:

use std::thread;

fn main() {
    let data = vec![42; 10];
    let more_data = "Important data".to_string();
    for _ in 1..=4 {
        thread::spawn(|| foo(data.clone(), more_data.clone()));
    }
}

fn foo(_data: Vec<u64>, _more_data: String) {}

这不会编译,因为克隆是在新线程上完成的,这可能会比主线程长。很公平,但似乎没有好的方法告诉 Rust 在主线程上进行克隆,然后然后将所有权转移到新线程。每当我遇到这个问题时,我都会这样做:

use std::thread;

fn main() {
    let data = vec![42; 10];
    let more_data = "Important data".to_string();
    for _ in 1..=4 {
        let cloned_data = data.clone();
        let cloned_more_data = more_data.clone();
        thread::spawn(move || foo(cloned_data, cloned_more_data));
    }
}

fn foo(_data: Vec<u64>, _more_data: String) {}

它可以满足我的要求,但它非常嘈杂和样板,尤其是有很多争论。有没有更好的办法?

【问题讨论】:

    标签: rust


    【解决方案1】:

    您可以使用iter::repeat() 为您克隆数据:

    use std::thread;
    
    fn main() {
        let data = vec![42; 10];
        let more_data = "Important data".to_string();
        let threads: Vec<_> = std::iter::repeat((data, more_data))
            .take(5)
            .map(|(data, more_data)| thread::spawn(|| foo(data, more_data)))
            .collect();
        let result: Vec<_> = threads.into_iter().map(|x| x.join()).collect();
        result.iter().for_each(|x| {
            println!("{:?}", x);
        });
    }
    
    fn foo(_data: Vec<u64>, _more_data: String) -> u64 {
        println!("Hello");
        42
    }
    

    【讨论】:

      【解决方案2】:

      有没有更好的办法?

      不,不使用标准库。对此有a proto-RFC about supporting some syntax,但这还远未发生。它确实有多种您今天可以使用的解决方案,例如enclose macro

      macro_rules! enclose {
          ( ($( $x:ident ),*) $y:expr ) => {
              {
                  $(let $x = $x.clone();)*
                  $y
              }
          };
      }
      

      这使您可以像这样编写代码:

      enclose!((data, more_data) {
          thread::spawn(move || foo(data, more_data));
      })
      

      【讨论】:

        猜你喜欢
        • 2022-12-04
        • 2021-04-18
        • 1970-01-01
        • 1970-01-01
        • 2012-07-08
        • 1970-01-01
        • 1970-01-01
        • 2019-03-10
        • 2023-03-10
        相关资源
        最近更新 更多