I have some multithreaded code that involves using a nested loop, where the inner one is run in parallel. "Shared" across each thread is a Sender
that will return results. Notably Sender
implements Send
so there should be no problem cloning it and sending it using Rayon's for_each_with()
. However, compiling this code:
use std::sync::mpsc::channel;
use rayon::prelude::*;
fn main(){
let (sender, receiver) = channel();
(0..5).for_each(|i|{
(0..5).into_par_iter().for_each_with(&sender, |sender, j|{
sender.send(i + j).unwrap();
});
});
}
Gives me:
8 | (0..5).into_par_iter().for_each_with(&sender, |sender, j|{
| ^^^^^^^ `Sender<_>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `Sender<_>`
= note: required because of the requirements on the impl of `Send` for `&Sender<_>`
Now I was thinking this might be because I'm trying to clone a reference, but if I move the actual sender
into for_each_with()
(ie for_each_with(sender, ...)
), it will be consumed by the first iteration of the outer loop:
error[E0507]: cannot move out of `sender`, a captured variable in an `FnMut` closure
(Playground).
How can I implement this pattern in a way that satisfies the Rust compiler?