当前位置:  开发笔记 > 编程语言 > 正文

传递给新线程的变量的生命周期

如何解决《传递给新线程的变量的生命周期》经验,为你挑选了1个好方法。

编译此程序时遇到问题:

use std::env;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    let args: Vec<_> = env::args().skip(1).collect();

    let (tx, rx) = mpsc::channel();

    for arg in &args {
        let t = tx.clone();

        thread::spawn(move || {
            thread::sleep(Duration::from_millis(50));
            let _new_arg = arg.to_string() + "foo";
            t.send(arg);
        });
    }

    for _ in &args {
        println!("{}", rx.recv().unwrap());
    }
}

我从命令行读取所有参数,并模拟对线程中的每个参数做一些工作.然后我打印出这项工作的结果,我使用一个频道.

error[E0597]: `args` does not live long enough
  --> src/main.rs:11:17
   |
11 |     for arg in &args {
   |                 ^^^^ does not live long enough
...
24 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

如果我理解得很好..生命周期args必须是static(即程序执行的整个时间),而它只存在于main函数范围内(?).我不明白这背后的原因,以及我如何解决它.



1> aepsil0n..:

问题在于产生后台线程.当你thread::spawn有效地调用你时,必须将其中使用的任何资源的所有权传递给线程,因为它可能无限期地运行,这意味着它的生命周期必须是'static.

有两种方法可以解决这个问题:最简单的方法是通过所有权.你的代码在这里

let new_arg = arg.to_string() + "foo";
t.send(arg);

看起来你真的想要发送new_arg,在这种情况下你可以arg.to_string()在产生线程之前创建自己的结果,从而消除传递引用的需要arg.

另一个稍微涉及的想法,虽然在某些方面可能有用,但是例如在横梁中实现的范围线程.这些绑定到一个显式范围,您可以在其中生成它们并在最后连接在一起.这看起来有点像这样:

crossbeam::scope(|scope| {
    scope.spawn(|| {
        println!("Hello from a scoped thread!");
    });
});

有关详细信息,请查看文档.


由于向量是`String`s的集合,并且在产生线程后没有使用,我只是将`arg` as-is移动到线程中 - [示例](http://is.gd/CMhQ7t).事实上,我甚至可以将这个集合避开到"Vec" - [例子](http://is.gd/vQcgWI).
推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有