Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

multithreading - Revisited: How to pass immutable parameters to a thread? (about lifetimes)

This my question was answered.

But when I modified the code a little, it does not work again with a compilation error similar to the error in the previous question. What is my error now?

use std::thread;

#[derive(Clone)]
struct Params<'a> {
    x: &'a i32,
}

struct State<'a> {
    params: &'a Params<'a>,
    y: i32,
}

impl<'a> State<'a> {
    fn new(params: &'a Params<'a>) -> Self {
        State {
            params,
            y: 0,
        }
    }
    fn start(&mut self) -> thread::JoinHandle<()> {
        let params = self.params.clone();
        thread::spawn(move || { params; /* ... */ })
    }
}
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/lib.rs:21:34
   |
21 |         let params = self.params.clone();
   |                                  ^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 13:6...
  --> src/lib.rs:13:6
   |
13 | impl<'a> State<'a> {
   |      ^^
note: ...so that the types are compatible
  --> src/lib.rs:21:34
   |
21 |         let params = self.params.clone();
   |                                  ^^^^^
   = note: expected `&Params<'_>`
              found `&Params<'a>`
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/lib.rs:22:23: 22:52 params:Params<'_>]` will meet its required lifetime bounds
  --> src/lib.rs:22:9
   |
22 |         thread::spawn(move || { params; /* ... */ })
   |         ^^^^^^^^^^^^^
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of using references I would suggest using a reference counted type (Arc), that way you do not need to worry about lifetimes.

use std::thread;
use std::sync::Arc;

#[derive(Clone)]
struct Params {
    x: i32,
}

struct State {
    params: Arc<Params>,
    y: i32,
}

impl State {
    fn new(params: &Arc<Params>) -> Self {
        State {
            params: params.clone(),
            y: 0,
        }
    }
    fn start(&self) -> thread::JoinHandle<()> {
        let params = self.params.clone();
        thread::spawn(move || { params; /* ... */ })
    }
}

If you want to mutate the state later on, you would need to wrap the Params type in the State struct with a Mutex like Arc<Mutex<Params>>.

More on the topic:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...