如何在 Rust 的线程之间正确使用 Arc<Mutex<Vec<u8>>> 上的 std::slice::Chunks ?

Rus*_*ofi 6 multithreading mutex reference-counting rust

我想了解为什么以下似乎在 Rust 中无法正常工作。

我想对一个向量进行分块,并给每个线程一个块来处理它。我尝试使用 Arc 和 Mutex 组合来相互访问我的 vec。

这是我的第一次(明显的)尝试:声明 vec,将其分块,将块发送到每个线程中。根据我的理解,它应该有效,因为 Chunk 方法保证不重叠的块。

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let data = Arc::new(Mutex::new(vec![0;20]));
    let chunk_size = 5;
    let mut threads = vec![];
    let chunks: Vec<&mut [u8]> = data.lock().unwrap().chunks_mut(chunk_size).collect();

    for chunk in chunks.into_iter(){
        threads.push(thread::spawn(move || {
                inside_thread(chunk)
            }));
    }

}
fn inside_thread(chunk: &mut [u8]) {
    // now do something with chunk
}
Run Code Online (Sandbox Code Playgroud)

该错误表明数据不够活跃。愚蠢的我,通过分块,我创建了指向数组的指针,但没有将 Arc 引用传递到线程中。所以我改变了几行,但这没有意义,因为我的线程中有一个未使用的引用!?

for i in 0..data.lock().unwrap().len() / 5 {
        let ref_to_data = data.clone();
        threads.push(thread::spawn(move || {
                inside_thread(chunk, ref_to_data)
            }));
    }
Run Code Online (Sandbox Code Playgroud)

该错误仍然表明数据不够活跃。

接下来的尝试也没有成功。我想好吧,我可以解决它,并将其在线程内分块,并通过索引获取我的块。但如果它有效,代码就不会很 rust 惯用:/

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let data = Arc::new(Mutex::new(vec![0;20]));
    let chunk_size = 5;
    let mut threads = vec![];

    for i in 0..data.lock().unwrap().len() / chunk_size {
        let ref_to_data = data.clone();
        threads.push(thread::spawn(move || {
                inside_thread(ref_to_data, i, chunk_size)
            }));
    }

}
fn inside_thread(data: Arc<Mutex<Vec<u8>>>, index: usize, chunk_size: usize) {
    let chunk: &mut [u8] = data.lock().unwrap().chunks_mut(chunk_size).collect()[index];
    // now do something with chunk
}
Run Code Online (Sandbox Code Playgroud)

错误说:

--> src/main.rs:18:72
   |
18 |     let chunk: &mut [u8] = data.lock().unwrap().chunks_mut(chunk_size).collect()[index];
   |                                                                        ^^^^^^^
   |                                                                        |
   |                                                                        cannot infer type for type parameter `B` declared on the method `collect`
   |                                                                        help: consider specifying the type argument in the method call: `collect::<B>`
   |
   = note: type must be known at this point
Run Code Online (Sandbox Code Playgroud)

当我尝试推断它时,它也不起作用。所以现在我尝试了很多,但没有任何效果,我没有想法。好吧,我总是能做的就是“自己做分块”。只需改变线程内的向量就可以正常工作。但这不是惯用的好方法(在我看来)。

问题:有没有可能的方法来解决这个问题 rust idiomatic?

提示:我知道我可以使用作用域线程池或类似的东西,但我想为我的论文获得这些知识。

非常感谢您花时间在这上面!

jaz*_*ock 0

我认为现在可以通过作用域线程来解决:

use std::thread;

fn main() {
    let mut data = vec![0;20];
    let chunk_size = 5;
    
    thread::scope(|s| {
        let mut threads = vec![];
        for chunk in data.chunks_mut(chunk_size) {
            let handle = s.spawn(move || {
                inside_thread(chunk)
            });
            threads.push(handle);
        }
        for handle in threads {
            handle.join().unwrap();
        }
    });
}

fn inside_thread(chunk: &mut [u8]) {
    // now do something with chunk
}
Run Code Online (Sandbox Code Playgroud)