如何定义闭包类型以发送到线程安全
How to define closure type to send into thread safetly
我正在尝试将闭包发送到线程中以进行如下处理:
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();
}
但是我收到一个错误:
F
无法在线程间安全发送
在高概览中我需要这样做(代码编译):
let closure = || env_variable.to_string();
thread::spawn(move || {
// before closure
closure();
// after closure
});
考虑到我需要捕获环境,我如何定义 F
以便将其发送到线程中。
如果你看一下thread::spawn
or thread::Builder::spawn
,你会发现它有签名
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
这意味着线程闭包 f
及其 return 值都必须实现 Send
特性(即可跨线程发送)并具有 'static
生命周期(即没有任何非静态生命周期的借用)。
如果所有捕获的变量都是闭包,则闭包将是 Send
。它也将是 'static
如果它的所有捕获变量都被移动到闭包中(这就是 move
关键字的作用)。
因为你的闭包中唯一捕获的变量是 work_load
,你需要确保 work_load
是 Send
和 'static
:
fn spawn<F>(work_load: F)
where
F: FnMut() + Send + 'static
// ^---.---^
// \_ add these constraints to F
我正在尝试将闭包发送到线程中以进行如下处理:
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();
}
但是我收到一个错误:
F
无法在线程间安全发送
在高概览中我需要这样做(代码编译):
let closure = || env_variable.to_string();
thread::spawn(move || {
// before closure
closure();
// after closure
});
考虑到我需要捕获环境,我如何定义 F
以便将其发送到线程中。
如果你看一下thread::spawn
or thread::Builder::spawn
,你会发现它有签名
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
这意味着线程闭包 f
及其 return 值都必须实现 Send
特性(即可跨线程发送)并具有 'static
生命周期(即没有任何非静态生命周期的借用)。
如果所有捕获的变量都是闭包,则闭包将是 Send
。它也将是 'static
如果它的所有捕获变量都被移动到闭包中(这就是 move
关键字的作用)。
因为你的闭包中唯一捕获的变量是 work_load
,你需要确保 work_load
是 Send
和 'static
:
fn spawn<F>(work_load: F)
where
F: FnMut() + Send + 'static
// ^---.---^
// \_ add these constraints to F