So I'm trying to implement multithreading in my application that generates images.
I generate a vector of closures, each of which generates one image. Then I create some threads and divide the work between the threads.
The code looks like that:
let (sender, receiver) = std::sync::mpsc::channel::<(usize, Image)>();
.
.
.
if ui.button("start").clicked() {
let mut images: Vec<Artpiece> = Vec::with_capacity(*batch_size);
let mut jobs: Vec<Box<dyn Fn() + Send + Sync + 'static>> = Vec::with_capacity(*batch_size);
for i in 0..*batch_size {
let artpiece = Artpiece::new(
Expression::random(*initial_complexity),
Expression::random(*initial_complexity),
Expression::random(*initial_complexity),
*resolution
);
let size_clone = resolution as u32;
let sender_clone = sender.clone();
let r_exp_clone = artpiece.expression_red.clone();
let g_exp_clone = artpiece.expression_green.clone();
let b_exp_clone = artpiece.expression_blue.clone();
jobs.push(Box::new(move || {
let mut img = Image::gen_image_color(size_clone as u16, size_clone as u16, color_u8!(50, 50, 50, 255));
for x in 0..size_clone {
for y in 0..size_clone {
// calculations omitted
}
}
sender_clone.send((i, img)).unwrap();
}));
images.push(artpiece);
}
let thread_num = 10;
let jobs_per_thread = jobs.len() as f32 / thread_num as f32;
let mut i = 0f32;
for _ in 0..thread_num {
let start = i as usize;
let end = (i + jobs_per_thread) as usize;
i += jobs_per_thread;
let jobs_slice = jobs.drain(start..end).collect::<Vec<_>>();
std::thread::spawn(move || {
for job in &jobs_slice[start..end] {
job();
}
});
}
}
In different place in code the receiver reads the messages and displays them.
The problem is, the compiler doesn't like me putting senders in closures that aren't defined inside thread::spawn
I'll put the error message below due to length limit.