@kornel I don't think that dependency is specially painful in Java, D, Kotlin...
Anyway we can discuss hours but I don' know how I can change my mind because the more I use Rust, the more I'm convinced. This is just my opinion. Downloading tons of crates to achieve a simple task is not my vision of simplicity specially when it comes to use an external crate to fulfill a simple requirement
Coming back to my problem, the most I can achieve without an external crate is:
fn parallel_sum<T>(v: Vec<T>, nb_threads: usize) -> T
where
T: 'static + Send + Sync + Debug + AddAssign + Default + Copy,
{
// this vector will hold created threads
let mut threads = Vec::new();
// need to arced the vector to share it
let arced = Arc::new(v);
// this channel will be use to send values (partial sums) for threads
let (sender, receiver) = mpsc::channel::<T>();
// create requested number of threads
for thread_number in 0..nb_threads {
// increment ref count, will be moved into the thread
let arced_cloned = arced.clone();
// each thread gets its invidual sender
let thread_sender = sender.clone();
// create thread and save ID for future join
let child = thread::spawn(move || {
// initialize partial sum
let mut partial_sum: T = T::default();
// this line doesn't compile:
// partial_sum = arced_cloned.into_iter().sum();
// trivial old style loop
for i in 0..arced_cloned.len() {
//
if i % nb_threads == thread_number {
partial_sum += *arced_cloned.get(i).unwrap();
}
}
// send our result to main thread
thread_sender.send(partial_sum).unwrap();
// print out partial sum
println!(
"thread #{}, partial_sum of modulo {:?} = {:?}",
thread_number, thread_number, partial_sum
);
});
// save thread ID
threads.push(child);
}
// wait for children threads to finish
for child in threads {
let _ = child.join();
}
// terminate sender and get final sum
//drop(sender);
let mut total_sum = T::default();
for _ in 0..nb_threads {
// main thread receives the partial sum from threads
let partial_sum = receiver.recv().unwrap();
// and get the final total sum
total_sum += partial_sum
}
total_sum
}
Probably sup-optimal but compiling and working. I found it incredibly painful for sharing an immutable value, not even touching mutation.
Thanks to @cuviper and this thread Why does thread::spawn need static lifetime for generic bounds? - #2 by lambda for a better understanding.