When trying to write some paralel code I keep getting hit with the error seen bellow. There are a few solutions I have found but they all involve locking which I would prefer not to do. Is there any way I can get round this?
pub trait PermBrute {
fn quadgram( &self, max_len: usize, ciphertext: &String ) -> Vec<usize> {
let mut vec : Vec<(f64, Vec<usize>)> = Vec::new();
let results = Arc::new(Mutex::new(vec));
let mut threads = vec![];
for i in 0..*CPUS {
threads.push( thread::spawn({
let clone = Arc::clone(&results);
let text = ciphertext.clone();
move || {
// some code here
let hold = self.decrypt( )
// some more code here
let mut v = clone.lock().unwrap();
v.push(best_key);
}
}));
}
for t in threads {
t.join().unwrap();
}
let lock = Arc::try_unwrap(results).expect("Lock still has multiple owners");
let mut hold = lock.into_inner().expect("Mutex cannot be locked");
// do some stuff with hold and return out
return out;
}
fn decrypt( &self, ciphertext : &String, key : &Vec<usize>) -> String;
}
error[E0277]: `Self` cannot be shared between threads safely
--> src/ciphers/cipher.rs:131:27
|
108 | fn quadgram( &self, max_len: usize, ciphertext: &String ) -> Vec<usize> {
| - help: consider further restricting `Self`: `where Self: std::marker::Sync`
...
131 | threads.push( thread::spawn({
| ^^^^^^^^^^^^^ `Self` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `Self`
= note: required because of the requirements on the impl of `std::marker::Send` for `&Self`
= note: required because it appears within the type `[closure@src/ciphers/cipher.rs:140:17: 164:18 text:std::string::String, start_len:usize, end_len:usize, count:usize, start_points_clone:std::vec::Vec<usize>, local_self:&Self, end:usize, clone:std::sync::Arc<std::sync::Mutex<std::vec::Vec<(f64, std::vec::Vec<usize>)>>>]`
Using the rayon crate, this can be done using the parallel iterator technique.