I'm using rust 1.24 on Win7-64.
I'm trying to process a bunch of files & to spread the processing over 4 threads. Here's the relevant part of my code:
pub struct Query {
pub case_sensitive: bool,
pub is_regex: bool,
pub pattern: String,
}
pub struct Reply {
pub filename: String,
pub pages: Vec<i32>,
}
pub fn process_files(query: Query, files: &Vec<PathBuf>) {
let (sender, receiver) = mpsc::channel();
for chunk in files.chunks(files.len() / 4) {
let asender = mpsc::Sender::clone(&sender);
thread::spawn(|| {
for filename in chunk { // process_file returns Option<Reply>
if let Some(reply) = process_file(&filename, query) {
asender.send(reply).unwrap();
}
}
});
}
for reply in receiver {
println!("{}: {:?}", reply.filename, reply.pages);
}
}
Unfortunately, it won't compile. Here's the error I get:
Compiling searchpdfscmd v0.1.1 (file:///R:/rs/searchpdfscmd_mpc)
error[E0277]: the trait bound `std::sync::mpsc::Sender<search::handler::Reply>: std::marker::Sync` is not satisfied
--> src\search\handler.rs:24:9
|
24 | thread::spawn(|| {
| ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<search::handler::Reply>` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<search::handler::Reply>`
= note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<search::handler::Reply>`
= note: required because it appears within the type `[closure@src\search\handler.rs:24:23: 30:10 chunk:&&[std::path::PathBuf], query:search::handler::Query, asender:&std::sync::mpsc::Sender<search::handler::Reply>]`
= note: required by `std::thread::spawn`
I don't understand why Reply isn't sendable.
PS I have a working version of this using rayon but on a 4 core machine it never uses more than 39% of the CPU (and the processing is all CPU-intensive). I also have a Python version (which uses multiprocessing) and is much faster because this one maxes out all the cores.