我正在尝试将闭包发送到线程中进行处理,例如:
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
或thread::Builder::spawn
,你会看到它有签名
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
这意味着线程闭包 f
及其返回值都必须实现 Send
特征(即可以跨线程发送)并具有'static
生命周期(即没有任何非静态生命周期的借用)。
如果所有捕获的变量都是,则闭包将被Send
。如果它的所有捕获变量都是静态的,并且所有捕获的变量都移动到闭包中(这就是 move
关键字的作用),它也将是 'static
。
由于闭包中唯一捕获的变量是 work_load
,因此您需要确保 work_load
既是 Send
又是 'static
:
fn spawn<F>(work_load: F)
where
F: FnMut() + Send + 'static
// ^---.---^
// \_ add these constraints to F
关于rust - 如何定义闭包类型以发送到线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61177864/