简体   繁体   English

Rust 横梁借用循环可变

[英]Rust crossbeam borrow mutable in a loop

I try to process an array with multiple worker threads, just like Rayon's par_iter() function, but i want to have a mutable reference target , one for each thread.我尝试处理具有多个工作线程的数组,就像 Rayon 的par_iter() function 一样,但我想要一个可变的引用target ,每个线程一个。

I have a simple function like this我有一个像这样的简单 function


pub fn parallel_map_vector<A:Sync,T:Send,B:Send>(a:&[A], t:&mut [T], b:&mut [B], f:impl Fn(&A,&mut T)+Send+Sync){
    assert_eq!(a.len(),b.len());
    let atomic_counter = AtomicUsize::new(0);
    crossbeam::scope(|scope| {
        for target in t {
            scope.spawn( |_| {
                loop {
                    let idx = atomic_counter.fetch_add(1, Ordering::Relaxed);
                    if idx < a.len() {unsafe{std::slice::from_raw_parts_mut(b,b_len)};
                        f(&a[idx], target)
                    }else{
                        break
                    }
                }
            });
        }
    }).unwrap();
}

For some reason i keep getting the error出于某种原因,我不断收到错误

error[E0373]: closure may outlive the current function, but it borrows `target`, which is owned by the current function
  --> htm/src/parallel.rs:11:26
   |
9  |     crossbeam::scope(|scope| {
   |                       ----- has type `&crossbeam::thread::Scope<'1>`
10 |         for target in t {
11 |             scope.spawn( |_| {
   |                          ^^^ may outlive borrowed value `target`
...
17 |                         f(&a[idx], target)
   |                                    ------ `target` is borrowed here
   |
note: function requires argument type to outlive `'1`
  --> htm/src/parallel.rs:11:13
   |
11 | /             scope.spawn( |_| {
12 | |                 loop {
13 | |                     let idx = atomic_counter.fetch_add(1, Ordering::Relaxed);
14 | |                     if idx < a.len() {
...  |
21 | |                 }
22 | |             });
   | |______________^
help: to force the closure to take ownership of `target` (and any other referenced variables), use the `move` keyword
   |
11 |             scope.spawn( move |_| {

but when i try it in rust playground it compiles without problem https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0a10cbfd2f135975f4682c843664d539 What could be wrong here?但是当我在 rust 操场上尝试它时,它编译没有问题https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0a10cbfd2f135975f3982可能是错误的48664 The code looks safe to me.代码对我来说看起来很安全。

The playground example to which you have linked is using the 2021 edition of Rust, which allows disjoint capture in closures (and hence the closure for each thread captures only target rather than the entire t slice).您链接到的操场示例使用的是 2021 版的 Rust,它允许在闭包中进行不相交的捕获(因此每个线程的闭包仅捕获target而不是整个t切片)。 If you switch to the 2018 edition , it yields the same error as in your question.如果您切换到 2018 edition ,它会产生与您的问题相同的错误。

Specify that you require the 2021 edition in your Cargo.toml (requires rustc >= 1.56.0).Cargo.toml中指定您需要 2021 版(需要 rustc >= 1.56.0)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM