Reputation: 5407
I'm trying to send a closure into a thread to process like:
fn spawn<F>(work_load: F) where F: FnMut() {
let builder = Builder::new();
let handler = builder.spawn(move || {
// Before process
work_load();
// After process
}).unwrap();
}
But I'm getting an error:
F
cannot be sent between threads safely
In a high overview I need to do this (code compiles):
let closure = || env_variable.to_string();
thread::spawn(move || {
// before closure
closure();
// after closure
});
How I can define F
so I can send it into thread, considering I need to capture environment.
Upvotes: 2
Views: 1458
Reputation: 40814
If you have a look at thread::spawn
or thread::Builder::spawn
, you will see that it has the signature
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
This means that both the thread closure f
and its return value must implement the Send
trait (i.e. be sendable across threads) and have a 'static
lifetime (i.e. not have any borrows with a non-static lifetime).
A closure will be Send
if all of its captured variables are. It will also be 'static
if all of its captured variables are and all captured variables are moved into the closure (which is what the move
keyword does).
Since the only captured variable in your closure is work_load
, you need to ensure that work_load
is both Send
and 'static
:
fn spawn<F>(work_load: F)
where
F: FnMut() + Send + 'static
// ^---.---^
// \_ add these constraints to F
Upvotes: 5