Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"the type does not fulfill the required lifetime" when using a method in a thread

I am trying to use a method in a thread in Rust, but I get the following error message

:21:10: 21:23 error: the type [closure@<anon>:21:24: 23:14 tx:std::sync::mpsc::Sender<i32>, self:&MyStruct, adder:i32, a:i32] does not fulfill the required lifetime :21
thread::spawn(move || { ^~~~~~~~~~~~~ :18:9: 24:10 note: in this expansion of for loop expansion note: type must outlive the static lifetime error: aborting due to previous error

This is the example code:

use std::thread;
use std::sync::mpsc;

struct MyStruct {
    field: i32
}

impl MyStruct {
    fn my_fn(&self, adder1: i32, adder2: i32) -> i32 {
        self.field + adder1 + adder2
    }

    fn threade_test(&self) {
        let (tx, rx) = mpsc::channel();
        let adder = 1;
        let lst_adder = vec!(2, 2, 2);

        for a in lst_adder {
            let tx = tx.clone();

            thread::spawn(move || {
                let _ = tx.send(self.my_fn(adder, a));
            });
        }

        println!("{}", rx.recv().unwrap());
    }
}

fn main() {
    let ms = MyStruct{field: 42};
    ms.threade_test();
}

Test it on the Rust Playground.

like image 662
Moebius Avatar asked Oct 30 '15 17:10

Moebius


1 Answers

The problem is that every variable moved to the thread must have the lifetime 'static. i.e. threads can't reference values which are not owned by the thread.

In this case the problem is that self is a reference to an instance of MyStruct.

To solve it, remove every reference and clone the structure before sending it to the thread.

use std::thread;
use std::sync::mpsc;

#[derive(Clone)]
struct MyStruct {
    field: i32
}

impl MyStruct {
    fn my_fn(&self, adder1: i32, adder2: i32) -> i32 {
        self.field + adder1 + adder2
    }

    fn threade_test(&self) {
        let (tx, rx) = mpsc::channel();
        let adder = 1;
        let lst_adder = vec!(2, 2, 2);

        for a in lst_adder {
            let tx = tx.clone();

            let self_clone = self.clone();
            thread::spawn(move || {
                let _ = tx.send(self_clone.my_fn(adder, a));
            });
        }

        println!("{}", rx.recv().unwrap());
    }
}

fn main() {
    let ms = MyStruct{field: 42};
    ms.threade_test();
}
like image 178
Moebius Avatar answered Nov 01 '22 06:11

Moebius