gpt4 book ai didi

multithreading - 无法在生成的线程中调用函数,因为它是 "does not fulfill the required lifetime"

转载 作者:行者123 更新时间:2023-11-29 08:10:56 24 4
gpt4 key购买 nike

我可以运行这段代码

fn testf(host: &str) {}

fn start(host: &str) {
testf(host);
testf(host);
}

但出于某种原因,我无法运行这个:

fn testf(host: &str) {}

fn start(host: &str) {
thread::spawn(move || testf(host));
thread::spawn(move || testf(host));
}

因为下面的错误

src/server.rs:30:5: 30:18 error: the type `[closure@src/server.rs:30:19: 30:38 host:&str]` does not fulfill the required lifetime
src/server.rs:30 thread::spawn(move || testf(host));
^~~~~~~~~~~~~
note: type must outlive the static lifetime
error: aborting due to previous error

谁能给我解释一下,它有什么问题以及如何解决?

最佳答案

你的闭包捕获一个字符串切片,因此它的环境的生命周期不长于这个切片的生命周期,但是 thread::spawn() 要求其参数具有静态生命周期:

pub fn spawn<F, T>(f: F) -> JoinHandle<T> 
where F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static

(注意 F: 'static 要求)

这是必要的,因为当线程由 thread::spawn() 生成时开始运行时,从中获取切片的字符串可能已经被破坏。 Rust 实际上已经防止了代码中的错误!

有几种方法可以修复它。

1) 最简单的方法是为每个线程克隆字符串:

fn start(host: &str) {
{
let host = host.to_owned();
thread::spawn(move || testf(&host));
}
{
let host = host.to_owned();
thread::spawn(move || testf(&host));
}
}

这样每个线程都会收到自己的字符串副本,该副本将在线程本身结束时销毁。

2) 如果你知道你的线程应该在 start() 之前完成功能结束,你可以使用像crossbeam这样的第三方库将引用传递给生成的线程:

extern crate crossbeam;

fn start(host: &str) {
crossbeam::scope(|scope| {
scope.spawn(move || testf(host));
scope.spawn(move || testf(host));
});
}

这边start()将等到两个线程都在 scoped() 中产生在返回之前已经完成,确保任何字符串 host指向的点不会被过早销毁。

以前这样的功能包含在标准库中,但它的实现方式was found to be unsound ,所以它被弃用了;此功能的适当替代品尚未添加回标准库。

3) 甚至另一种选择是使用 Arc<String>在线程之间共享字符串,但这需要在 start() 之外进行更重大的更改:

use std::sync::Arc;

fn start(host: Arc<String>) {
{
let host = host.clone();
thread::spawn(move || testf(&host));
}
{
let host = host.clone();
thread::spawn(move || testf(&host));
}
}

使用这种方法,您需要将字符串保存在 Arc 中(这是一个“原子引用计数”指针),因此这需要您更改调用 start() 的代码.克隆可能更好。当然,如果你想分享不&str但是&SomeStruct其中 SomeStruct很大和/或不可克隆,无法避免范围异或 Arc .

关于multithreading - 无法在生成的线程中调用函数,因为它是 "does not fulfill the required lifetime",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33938547/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com