fail: Threads want full ownership, do another way
Saving for reference more than anything. The threads take ownership of the data (the closures do, but whatever). Moving the return channel out of the dispatcher means the dispatcher can't be moved into the feeder thread. I see a few solutions from here: 1. Proxy the return channel with another channel. Give the whole dispatcher to the feeder thread and hook up another output channel. Have the feeder unload the return and pass it through. 2. Rewrite the dispatcher constructor to pass a tuple of the dispatcher minus it's return channel, and the return channel now as a separate object. This could let them have independent lifetimes and then I can pass them around like I'm trying to do. 3. Have main do all the job feeding, result unloading, and recompositing. Don't have a feeder and collector thread, and just have main bounce between loading a few, and unloading a few.
This commit is contained in:
16
src/main.rs
16
src/main.rs
@@ -18,6 +18,8 @@ use rand::{Rng, SeedableRng};
|
||||
use rand::rngs::SmallRng;
|
||||
use rand::distributions::Uniform;
|
||||
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
// image
|
||||
let aspect_ratio = 3.0 / 2.0;
|
||||
@@ -62,8 +64,12 @@ fn main() {
|
||||
samples_per_pixel,
|
||||
world,
|
||||
};
|
||||
let mut dispatcher = thread_utils::Dispatcher::new(&small_rng);
|
||||
|
||||
thread::scope(|s| {
|
||||
let mut dispatcher = thread_utils::Dispatcher::new(&small_rng);
|
||||
let scanline_receiver = dispatcher.render_rx;
|
||||
|
||||
s.spawn(move || {
|
||||
for y in (0..image.1).rev() {
|
||||
eprintln!("Submitting scanline: {}", y);
|
||||
let job = RenderCommand::Line { line_num: y, context: context.clone() };
|
||||
@@ -77,14 +83,18 @@ fn main() {
|
||||
dispatcher.submit_job(RenderCommand::Stop);
|
||||
dispatcher.submit_job(RenderCommand::Stop);
|
||||
// ... also I happen to know there are 4 threads.
|
||||
|
||||
while let Ok(scanline) = dispatcher.render_rx.recv() {
|
||||
});
|
||||
eprintln!("Reached the scanline collector");
|
||||
while let Ok(scanline) = scanline_receiver.recv() {
|
||||
//TODO: sort results once multiple threads are introduced.
|
||||
eprintln!("Received scanline: {}", scanline.line_num);
|
||||
for color in scanline.line {
|
||||
println!("{}", color.print_ppm(samples_per_pixel));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// TODO: Dispatcher shutdown mechanism. Right now, we might technically be leaking threads.
|
||||
eprintln!("Done!");
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ impl Dispatcher {
|
||||
|
||||
for _ in 0..4 {
|
||||
// create new command tx/rx pairs. Store tx in the list, give rx to the thread.
|
||||
let (command_tx, command_rx) = mpsc::sync_channel::<RenderCommand>(100);
|
||||
let (command_tx, command_rx) = mpsc::sync_channel::<RenderCommand>(1);
|
||||
// TODO: Pick appropriate command queue depth (or make it controllable, even)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user