Rust线程池机箱如何在迭代器上执行



Cargo.toml

threadpool = "1.8.1"

我正在使用线程池板条箱,只是为了学习的目的,如果有一些更好的线程池板条箱内,请通知我。

有问题的代码,简化版本:

use threadpool::ThreadPool;
fn main() {
let pool = ThreadPool::new(4);
let v2 = vec!["a".to_string(), "b".to_string(), "c".to_string(), ];

for i in v2.iter() { // .iter() is the problem
pool.execute(move || println!("{}", i));
}

pool.join();
}

错误:

error[E0597]: `v2` does not live long enough
for i in v2.iter() { // .iter() is the problem
|                  ^^^^^^^^^ borrowed value does not live long enough
pool.execute(move || println!("{}", i));
|             --------------------------------------- argument requires that `v2` is borrowed for `'static`

它在没有.iter()的情况下工作得很好。我之所以使用它,是为了在我的代码中进行演示。我使用iter和zip到iter到大小相同的2个vec,都是String类型,例如urls.iter().zip(files_t4.iter())

我确实理解为什么我有错误,但不知道如何解决
我知道这类似于如何将对堆栈变量的引用传递给线程?,但除了尝试另一个板条箱之外,不确定是否可以像第一个例子中那样使用std::thread::scope
我正在学习如何在Rust中下载文件,以及如何使用线程池完成下载
欢迎提出任何想法。

我确实理解为什么我有错误,但不知道如何解决?

使用.into_iter,或者直接在向量上迭代(做同样的事情)。

因为您使用的是iter,所以迭代器是借用的,所以i的类型是&String,因此会触发一个生存期错误,因为编译器不知道作用域的寿命将超过线程池。

不确定是否可以像第一个例子中那样使用std::thread::scope。

是的,但是您必须实现;线程池";手动操作,因为线程池机箱不支持作用域线程/任务。或者,使用Rayon,除了并行迭代器之外,它还提供显式线程池和作用域任务。它还提供了其他有趣的并行工具,例如广播、联接,当然还有派生。

最新更新