当使用 ThreadPool 传递带有引用的 Arc 时会产生"data escapes the function body"错误,传递数据本身的 Arc 工作正常



我已经编写了一些代码来将计算的独立块分解成块,然后将每个块提供给线程池,然后执行计算并将结果通过mpsc传递回主线程。

代码如下:

pub fn impute(pbwt_data : Arc<&pbwt::PbwtInfo>, test_sequences : Vec<Vec<u8>>) -> Vec<Vec<u8>> {
let N = test_sequences.len();
let mut fin_imputed: Vec<Vec<u8>> = vec![Vec::new();N];
let safe_pbwt = Arc::new(pbwt_data);
let (tx,rx) = mpsc::channel();
let pool = ThreadPool::new(8);
let mut i = 0;
for tst_seq in test_sequences.into_iter(){
let txr = tx.clone();
let safe_test_seq = Arc::new(tst_seq);
let refer = Arc::clone(&safe_pbwt);
let clo = closure!(move txr, move refer, move safe_test_seq, || {
let val = impute_single(&refer,&safe_test_seq);
let ret = RowWPos { position: i as u32, row: val};
txr.send(ret).unwrap();
});

pool.execute(clo);
i += 1;
}
drop(tx);
for recd in rx.iter() {
fin_imputed[recd.position as usize] = recd.row;
}
return fin_imputed;
}

内部impute_single函数引用一个PbwtInfo对象和一个Vec<u8>对象。内部函数不以任何方式修改PbwtInfo对象,它只是从中读取。

不幸的是,当我试图运行它时,这段代码产生了一个错误:

error[E0521]: borrowed data escapes outside of function
--> pbwt_hkhan/src/imputer.rs:138:9
|
111 | pub fn impute(pbwt_data : Arc<&pbwt::PbwtInfo>, test_sequences : Vec<Vec<u8>>) -> Vec<Vec<u8>> {
|               ---------       - let's call the lifetime of this reference `'1`
|               |
|               `pbwt_data` is a reference that is only valid in the function body
...
138 |         pool.execute(clo);
|         ^^^^^^^^^^^^^^^^^
|         |
|         `pbwt_data` escapes the function body here
|         argument requires that `'1` must outlive `'static`
For more information about this error, try `rustc --explain E0521`.
error: could not compile `pbwt_hkhan` due to previous error

我可以通过将函数签名中的pbwt_data : Arc<&pbwt::PbwtInfo>更改为pbwt_data : Arc<pbwt::PbwtInfo>并直接使用PbwtInfo对象创建Arc而不是在将其提供给函数之前引用它来修复此错误。然而,这意味着我的对象现在卡在Arc内部,并且在下游有进一步的代码,我想再次使用PbwtInfo对象。

我可以克隆它,但它是一个相当大的和昂贵的对象创建一个副本,所以我宁愿不这样做。理想情况下,我想要一个解决方案,我甚至不必将Arc传递给impute函数,并且可以只使用&PbwtInfo,因为它或它调用的任何东西都不会修改pbwt_data。我知道我可以做到这一点,如果不是将计算分割成块并使用线程池,我只是使用单个线程,所以我觉得这应该是可能的。

使用Arc<pbwt::PbwtInfo>作为类型。要再次检索对象,可以使用Arc::try_unwrap(your_arc),如果只剩下一个强引用,它将给出该对象。

相关内容

  • 没有找到相关文章

最新更新