如何定义闭包类型以发送到线程安全

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_loadSend'static:

fn spawn<F>(work_load: F)
where
    F: FnMut() + Send + 'static
//               ^---.---^
//                   \_ add these constraints to F