在Rust中的线程之间共享函数引用

在Rust中的线程之间共享函数引用,rust,Rust,我想在线程之间共享函数引用,但是Rust编译器说不能在线程之间安全地共享`dyn for std::string::string`。在线程之间共享“常规”值时,我非常了解Send、Sync和Arc,但在这种情况下,我无法理解问题所在。函数在程序运行时有一个静态地址,因此我看不出有什么问题 我怎样才能做到这一点 fn main() { // pass a function.. do_sth_multithreaded(&append_a); do_sth_multi

我想在线程之间共享函数引用,但是Rust编译器说不能在线程之间安全地共享
`dyn for std::string::string`。在线程之间共享“常规”值时,我非常了解
Send
Sync
Arc
,但在这种情况下,我无法理解问题所在。函数在程序运行时有一个静态地址,因此我看不出有什么问题

我怎样才能做到这一点

fn main() {
    // pass a function..
    do_sth_multithreaded(&append_a);
    do_sth_multithreaded(&identity);
}

fn append_a(string: &String) -> String {
    let mut string = String::from(string);
    string.push('a');
    string
}

fn identity(string: &String) -> String {
    String::from(string)
}

fn do_sth_multithreaded(transform_fn: &dyn Fn(&String) -> String) {
    for i in 0..4 {
        let string = format!("{}", i);
        thread::spawn(move || {
            println!("Thread {}: {}", i, transform_fn(&string))
        });
    }
}
函数在程序运行时有一个静态地址,因此我看不出有什么问题

这对于函数来说很好,但是您正在传递一个
&dyn Fn
,这也可以是一个闭包或者(在不稳定的情况下)一个实现该特性的自定义对象。并且此对象可能没有静态地址。因此,您不能保证对象将比您生成的线程更长寿

但这甚至不是编译器所抱怨的(现在!)。它实际上在抱怨它不知道是否允许您从另一个线程访问
Fn
。同样,与函数指针无关,但与闭包相关

以下是一个适用于您的示例的签名:

fn do_sth_multithreaded(transform_fn: &'static (dyn Fn(&String) -> String + Sync))
请注意
静态
生存期绑定和
同步
绑定

但是,在这种情况下,静态生存期是有效的,这可能意味着您永远无法发送闭包。为了实现这一点,您需要使用一个作用域线程系统(例如,从
横梁
板条箱),以确保
多线程
在返回之前等待线程完成。然后,您可以放松静态生命周期界限

函数在程序运行时有一个静态地址,因此我看不出有什么问题

这对于函数来说很好,但是您正在传递一个
&dyn Fn
,这也可以是一个闭包或者(在不稳定的情况下)一个实现该特性的自定义对象。并且此对象可能没有静态地址。因此,您不能保证对象将比您生成的线程更长寿

但这甚至不是编译器所抱怨的(现在!)。它实际上在抱怨它不知道是否允许您从另一个线程访问
Fn
。同样,与函数指针无关,但与闭包相关

以下是一个适用于您的示例的签名:

fn do_sth_multithreaded(transform_fn: &'static (dyn Fn(&String) -> String + Sync))
请注意
静态
生存期绑定和
同步
绑定


但是,在这种情况下,静态生存期是有效的,这可能意味着您永远无法发送闭包。为了实现这一点,您需要使用一个作用域线程系统(例如,从
横梁
板条箱),以确保
多线程
在返回之前等待线程完成。然后你可以放松静态生命周期限制。

我知道这篇文章。但是我仍然想学习和理解为什么它没有像我想象的那样工作。为什么要使用
&dyn Fn
而不是函数指针?
多线程
也应该与闭包一起工作吗?这还不是一个要求,不。也许将来会是。我不知道“真正的”函数指针。它适用于此函数定义
fn do\u sth\u多线程(transform\u fn:fn(&String)->String)
-谢谢!调用如下:
do\u sth\u多线程(identity)我知道这篇文章。但是我仍然想学习和理解为什么它没有像我想象的那样工作。为什么要使用
&dyn Fn
而不是函数指针?
多线程
也应该与闭包一起工作吗?这还不是一个要求,不。也许将来会是。我不知道“真正的”函数指针。它适用于此函数定义
fn do\u sth\u多线程(transform\u fn:fn(&String)->String)
-谢谢!调用如下:
do\u sth\u多线程(identity)