Я бы хотел понять, почему в Rust не работает следующее.
Я бы хотел разделить вектор на части и дать каждому потоку фрагмент для работы с ним. Я попробовал это с комбинацией Ar c и Mutex, чтобы иметь взаимный доступ к моей ve c.
Это была моя первая (очевидная) попытка: объявить ve c, разделить на части, отправить кусок в каждую нить. В моем понимании это должно работать, потому что методы 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
}
Ошибка говорит о том, что данные не живут достаточно. Глупый я, с помощью чанковки я создал указатели на массив, но не передавал ссылку Ar c в поток. Поэтому я изменил несколько строк, но это не имело бы никакого смысла, потому что в моем потоке была бы неиспользованная ссылка!?
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)
}));
}
Ошибка по-прежнему говорит о том, что данные не живут достаточно. 1012 * Следующая попытка тоже не сработала. Я думал, хорошо, я мог бы обойти это и разделить его на части в потоке и получить свой кусок по индексу. Но если бы это работало, код не был бы очень идиоматическим c: /
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
}
Ошибка говорит:
--> 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
И когда я пытаюсь сделать вывод, это не ' тоже не работает. Так что сейчас я очень старался, и ничего не получалось, и у меня не было идей. Хорошо, что я всегда мог сделать, это "сделать порцию самостоятельно". Просто мутирование вектора внутри потоков работает нормально. Но это не идиоматизм c хороший способ сделать это (на мой взгляд).
Вопрос: есть ли способ решить эту проблему? Ржавчина идиомати c?
Подсказка: я знаю, что могу работать с пулом с ограниченным доступом или чем-то вроде этого, но я хочу получить эти знания для своей диссертации.
Большое спасибо, что уделили нам время на это!