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?
提示:我知道我可以使用作用域线程池或类似的东西,但我想为我的论文获得这些知识。
非常感谢您花时间在这上面!
我认为现在可以通过作用域线程来解决:
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)