延长线程变量的生命周期

问题描述 投票:0回答:1

我正在从文件中读取一个字符串,将其按行分割成一个向量,然后我想在单独的线程中对提取的行进行一些操作。像这样:

use std::fs::File;
use std::io::prelude::*;
use std::thread;
fn main() {
    match File::open("data") {
        Ok(mut result) => {
            let mut s = String::new();
            result.read_to_string(&mut s);
            let k : Vec<_> = s.split("\n").collect();
            for line in k {
                thread::spawn(move || {
                    println!("nL: {:?}", line);
                });
            }
        
        }
        Err(err) => {
            println!("Error {:?}",err);
        }
    }
}

当然,这会引发错误,因为

s
将在线程启动之前超出范围:

error[E0597]: `s` does not live long enough
  --> src/main.rs:9:30
   |
7  |             let mut s = String::new();
   |                 ----- binding `s` declared here
8  |             result.read_to_string(&mut s);
9  |             let k : Vec<_> = s.split("\n").collect();
   |                              ^------------
   |                              |
   |                              borrowed value does not live long enough
   |                              argument requires that `s` is borrowed for `'static`
...
16 |         }
   |         - `s` dropped here while still borrowed

我现在能做什么?我尝试了很多类似

Box
Arc
的方法,但我无法让它工作。我不知何故需要创建
s
的副本,它也存在于线程中。但我该怎么做呢?

multithreading rust lifetime
1个回答
4
投票

从根本上来说,问题在于

line
s
的借用切片。 您在这里实际上无能为力,因为无法保证每个
line
不会比
s
本身更长寿。

另外,需要明确的是:Rust 中绝对没有办法“延长变量的生命周期”。 这根本做不到。

解决这个问题最简单的方法是从

line
借来变成拥有。 像这样:

use std::thread;
fn main() {
    let mut s: String = "One\nTwo\nThree\n".into();
    let k : Vec<String> = s.split("\n").map(|s| s.into()).collect();
    for line in k {
        thread::spawn(move || {
            println!("nL: {:?}", line);
        });
    }
}

.map(|s| s.into())
&str
转换为
String
。 由于
String
拥有其内容,因此可以安全地将其移至每个线程的闭包中,并且将独立于创建它的线程而存在。

注意:你可以使用新的作用域线程 API 在夜间 Rust 中执行此操作,但这仍然不稳定。

© www.soinside.com 2019 - 2024. All rights reserved.