5

I am trying to fire up a new thread using some heap data in Rust and I am getting a bunch of errors that stem from the need of the data to have 'static lifetime. I've worked my way backwards up my program but hit a problem.

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

struct ThreadData {
    vector_of_strings: Vec<String>,
    terms: Vec<&'static str>,
    quotient: usize,
}

fn perform_search(slice: &[String], terms: &[&str]) {
    /* ... */
}

fn threaded_search(td_arc: &Arc<ThreadData>) {
    let no_of_lines = td_arc.vector_of_strings.len();
    let new_tda1 = td_arc.clone();

    let strings_as_slice1 = new_tda1.vector_of_strings.as_slice();   

    thread::spawn(move || {
        perform_search(&strings_as_slice1[0..td_arc.quotient], &new_tda1.terms);
    });
}

fn main() {
    let td = ThreadData {
        vector_of_strings: Vec::new(),
        terms: Vec::new(),
        quotient: 0,
    };

    let td_arc = Arc::new(td);
    threaded_search(&td_arc);
}

Error:

error[E0621]: explicit lifetime required in the type of `td_arc`               
  --> src/main.rs:20:5                                                         
   |                                                                           
14 | fn threaded_search(td_arc: &Arc<ThreadData>) {                            
   |                            ---------------- help: add explicit lifetime `'static` to the type of `td_arc`: `&'static std::sync::Arc<ThreadData>`
...                                                                            
20 |     thread::spawn(move || {                                               
   |     ^^^^^^^^^^^^^ lifetime `'static` required
dtolnay
  • 9,621
  • 5
  • 41
  • 62
the_endian
  • 2,259
  • 1
  • 24
  • 49
  • 1
    Your code does not compile. Please create a [MCVE](https://stackoverflow.com/help/mcve) (there are some good infos about a mcve in the [rust tag](https://stackoverflow.com/tags/rust/info) as well). Next you should clarify question (is it about *"Do I really need to use static references"*, or do you want that your code compiles?). Pleas edit your question. – hellow Sep 21 '18 at 06:23
  • 2
    The title question is answered by [How can I pass a reference to a stack variable to a thread?](https://stackoverflow.com/questions/32750829/how-can-i-pass-a-reference-to-a-stack-variable-to-a-thread) However, I don't think that's necessary here since you can just *move* the `Vec` into the `ThreadData` and clone the `Arc`. I suspect you are confused by the difference between `&'static T` and `T: 'static`; they mean different things. For more targeted advice an MCVE would help a lot. – trent Sep 21 '18 at 12:07
  • @trentcl I've tried to make this an MCVE but please note of course it's not going to compile, that's why I'm asking the question. – the_endian Sep 21 '18 at 14:54
  • @hellow I've tried to clarify as best as I can, thank you. – the_endian Sep 21 '18 at 14:55
  • 1
    Please review how to create a [MCVE] and then [edit] your question to include it. We cannot tell what crates, types, traits, fields, etc. are present in the code. Notably, numerous imports are missing and you don't even have balanced curly braces. Try to produce something that reproduces your error on the [Rust Playground](https://play.rust-lang.org) or you can reproduce it in a brand new Cargo project. There are [Rust-specific MCVE tips](//stackoverflow.com/tags/rust/info) as well. – Shepmaster Sep 21 '18 at 15:00
  • @Shepmaster ah ok sorry, having some difficulty here getting it so that it is concise enough but also complete. Will read... Who knows maybe doing that will also lead me to the answer lol. – the_endian Sep 21 '18 at 15:03

1 Answers1

4

The error about 'static is because the new thread created within thread::spawn may outlive the invocation of threaded_search during which the thread is initially created, which means the thread must not be permitted to use any local variables from threaded_search with a lifetime shorter than 'static.

In your code the new thread is referring to strings_as_slice1 and td_arc.

Generally with thread::spawn and Arc you will want to move ownership of one reference count into the thread and have the thread access whatever it needs through that reference counted pointer rather than from the enclosing short-lived scope directly.

fn threaded_search(td_arc: &Arc<ThreadData>) {
    // Increment reference count that we can move into the new thread.
    let td_arc = td_arc.clone();

    thread::spawn(move || {
        perform_search(&td_arc.vector_of_strings[0..td_arc.quotient], &td_arc.terms);
    });
}
dtolnay
  • 9,621
  • 5
  • 41
  • 62