传递给新线程的变量的生命周期 [英] Lifetime of variables passed to a new thread

查看:28
本文介绍了传递给新线程的变量的生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编译这个程序时遇到问题:

I have trouble compiling this program:

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());
    }
}

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

I read all arguments from the command line and emulate doing some work on each argument in the thread. Then I print out the results of this work, which I do using a channel.

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 函数 (?).我不明白这背后的原因,以及如何解决它.

If I understood well.. the lifetime of args must be static (i.e. the entire time of program execution), while it only lives within the scope of main function (?). I don't understand the reason behind this, and how I could fix it.

推荐答案

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

The problem lies in spawning a background thread. When you call thread::spawn you effectively have to pass ownership of any resource used in it to the thread, as it might run indefinitely, which means that its lifetime must be 'static.

有两种方法可以解决这个问题:最简单的一种方法是传递所有权.您的代码在这里

There are two options to resolve that: the simplest one would be to pass ownership. Your code here

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

看起来您实际上想要发送 new_arg,在这种情况下,您可以在生成线程之前创建 arg.to_string() 的拥有结果,从而消除需要传递引用arg.

looks like you actually wanted to send new_arg, in which case you could just create the owned result of arg.to_string() before spawning the thread, thus eliminating the need to pass the reference arg.

另一个稍微复杂的想法,但在某些时候可能有用,例如在 crossbeam 中实现的作用域线程.这些被绑定到一个明确的范围,在那里你产生它们并在最后连接在一起.这看起来有点像这样:

Another slightly more involved idea, that might be useful at some point though, are scoped threads as implemented in crossbeam for example. These are bound to an explicit scope, where you spawn them and are joined together at the end. This looks somewhat like this:

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

查看文档了解更多详情.

这篇关于传递给新线程的变量的生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆