使用线程时 Rust 中 self 参数的生命周期 [英] The lifetime of self parameter in Rust when using threads

查看:199
本文介绍了使用线程时 Rust 中 self 参数的生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 Rust,我有这个代码:

I'm in the process of learning Rust and I have this code:

use std::sync::{Arc, Mutex};
use std::thread::spawn;

pub struct MyText {
    my_text: Mutex<Vec<String>>,
}

pub trait MyTextOptions {
    fn add(&self, t: String);
}

impl MyTextOptions for MyText {
    fn add(&self, text: String) {
        let int_text = Arc::new(self);
        let put_into_my_text = spawn(move || {
            let mut text_feed = int_text.my_text.lock().unwrap();
            text_feed.push(text)
        });
        put_into_my_text.join();
    }
}

当我尝试运行它时,我得到:

When I try to run it I get:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src\buffer.rs:37:33
   |
37 |         let int_text = Arc::new(self);
   |                                 ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 36:5...
  --> src\buffer.rs:36:5
   |
36 | /     fn add(&self, text: String) {
37 | |         let int_text = Arc::new(self);
38 | |         let put_into_my_text = spawn(move || {
39 | |             let mut text_feed = int_text.my_text.lock().unwrap();
...  |
42 | |         put_into_my_text.join();
43 | |     }
   | |_____^
   = note: ...so that the expression is assignable:
           expected &buffer::MyText
              found &buffer::MyText
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src\buffer.rs:38:38: 41:10 int_text:std::sync::Arc<&buffer::MyText>, text:std::string::String]` will meet its required lifetime bounds
  --> src\buffer.rs:38:32
   |
38 |         let put_into_my_text = spawn(move || {
   |

在使用线程时,我似乎无法理解 Rust 中变量的生命周期.不管我用这个函数做什么,我仍然会遇到这种类型的错误.

I seem to fail to understand the lifetime of variables in rust when using threads. No matter what I do with this function I'm still getting this type of error.

推荐答案

通过 thread::spawn 产生的线程理论上可以比其父线程存活时间更长.如果子线程可以引用来自父线程的数据,则当父线程停止时,这些引用将悬空(无效).这表示为 'static 绑定在给 thread::spawn 的闭包上.编译器无法理解您加入同一函数中的线程这一事实,因此该限制仍然有效.

A thread spawned via thread::spawn can in theory outlive its parent thread. If the child thread could reference data from the parent thread, these reference would dangle (be invalid) when the parent thread stops. This is expressed as a 'static bound on the closure given to thread::spawn. The fact that you join the thread in the same function is not understood by the compiler, so the restriction still holds.

您已经尝试使用 Arc(大概是为了解决这个问题),但是您正在创建 selfArc,它是已经参考.因此,您只是将引用放入 Arc.该值不满足 'static 界限,这就是您收到错误的原因.

You already tried to use an Arc (presumably to get around this problem), but you are creating an Arc of self which is a reference already. So you are just putting a reference into an Arc. That value does not satisfy the 'static bound, that's why you are getting an error.

有多种方法可以解决这个问题,许多方法取决于您项目的整体架构.最简单的方法之一是使用 crossbeam(或者特别是 crossbeam_utils)中的 scoped:

There are multiple ways to solve this problem, many depend on the overall architecture of your project. One of the easiest ways is to use scoped from crossbeam (or specifically, crossbeam_utils):

use crossbeam_utils::thread;

impl MyTextOptions for MyText {
    fn add(&self, text: String) {
        thread::scope(|s| {
            s.spawn(|_| {
                let mut text_feed = self.my_text.lock().unwrap();
                text_feed.push(text)
            });
        }).unwrap();
    }
}

这是一个花哨的辅助函数,通过确保子线程在父线程结束之前结束,它实际上允许您从父作用域借用值.

This is a fancy helper function that actually lets you borrow values from the parent scope by ensuring the child thread ends before the parent thread does.

另一种解决方案是将 MyText 值放入 Arc(特别是:按值,而不是按引用).然后你可以多次克隆这个 Arc 并将它发送到一个新线程.但这意味着您不能使用以 &self 作为接收者的方法,而必须以另一种方式解决它.

Another solution would be to put the MyText value into an Arc (notably: by value, not by reference). Then you can clone this Arc a bunch of times and send it to a new thread. But this means you cannot use methods that take &self as receiver, but you have to solve it in another way.

这篇关于使用线程时 Rust 中 self 参数的生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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