Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lifetime of variables passed to a new thread

Tags:

rust

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...

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.

like image 257
Ernest Avatar asked Dec 23 '15 16:12

Ernest


People also ask

How to pass arguments in a thread?

/* Code Listing 6.9: Passing multiple arguments to a thread requires grouping them into a struct */ /* Assume we have: struct thread_args { int first; const char *second; }; */ struct thread_args *args = malloc (sizeof (struct thread_args)); args->first = 5; args->second = "Hello"; /* Note that the data structure ...

How to pass argument to thread in c?

Example 1 - Thread Argument Passing long taskids[NUM_THREADS]; for(t=0; t<NUM_THREADS; t++) { taskids[t] = t; printf("Creating thread %ld\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]); ... }

How to pass two arguments to thread in c?

if you declare parameter to be an array of int ("int parameter[2];"), then you can pass parameter as a pointer. It is the pointer to first int. You can then access it from the thread as an array.

Which function is used to return a value from the thread back to the main process?

The decorated function creates a new thread each time it's called and returns a Thread object that contains the queue that will receive the result.


1 Answers

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

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.

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!");
    });
});

Have a look at the docs for further details.

like image 139
Emilia Bopp Avatar answered Sep 20 '22 01:09

Emilia Bopp