I'm writing some parallel computing code using rayon and need the threads to access some shared mutable state. Compiler says no so I plan to use the superpower of unsafe and share a raw pointer between threads and dereference it in the thread.
Now that *mut T is !Send and !Sync, I need to make a wrapper struct and mark it as Sync and share that struct between threads. But following code doesn't compile. playground
use rayon::prelude::*;
struct PtrWrapper(*const ());
unsafe impl Sync for PtrWrapper {}
fn main() {
let ptr_wrapper = PtrWrapper(&() as _);
(0..10).into_par_iter().for_each(|_| {
ptr_wrapper.0;
});
}
Compiler says
`*const ()` cannot be shared between threads safely
But I'm not sharing *const (). I'm sharing PtrWrapper. What am I doing wrong?
You probably shouldn't use unsafe for those reasons. You should instead use some locking mechanisms (Arc<Mutex<T>> typically) or communicate via channels:
let state = 1;
let (sender, receiver) = crossbeam::channel::bounded(64);
let (a, _) = rayon::join(
move || {
// do something with the receiver and your state
},
move || {
(0..10).into_par_iter().for_each_with(sender, |sender, i| {
sender.send(i).unwrap()
});
}
);
Thanks guys for your suggestion on "don't do this". I'm intentionally not using Mutex or channel because the code is going to compile to both spirv and cpu. All I have is limited form atomics.