How to run a member function in a thread from another member function

Hi
In my struct, I have a worker member function and a runner member function.
I want to start the worker function thread from the runner function, code example: Rust Playground
I'm getting this error:

error[E0521]: borrowed data escapes outside of method
  --> src/main.rs:17:9
   |
16 |       pub fn runner(&self) {
   |                     -----
   |                     |
   |                     `self` is a reference that is only valid in the method body
   |                     let's call the lifetime of this reference `'1`
17 | /         thread::spawn(move || {
18 | |             self.worker();
19 | |         });
   | |          ^
   | |          |
   | |__________`self` escapes the method body here
   |            argument requires that `'1` must outlive `'static`

Is there a way to do it?

Use thread::scope(). Read the documentation of thread::spawn() for an explanation of why it doesn't work when the worker captures a reference.

2 Likes

In case you don't want to wait for your worker to finish inside of your runner method (which would be the case when you'd use thread::scope), you could also wrap your struct in an Arc and pass a clone to your worker thread: playground.

4 Likes

Thanks @jofas @H2CO3 !
you solved my problem.
What's the tradeoff between the two methods?
Which one is better for my usage? more efficient?

That depends on what your intentions are. If you want runner to wait till your worker has finished running, I'd use thread::scope. If you want to simply spawn your worker and let it run concurrently to your main thread (which I'd expect based on the naming of your variables), I'd use Arc<Self> to pass the data needed by your worker to the worker thread.

1 Like

There should be no discernible difference. A thread being spawned is a thread being spawned. Lifetimes have zero impact on runtime; whether some associated handle has a 'static or non-'static lifetime won't make anything inherently more or less efficient.

1 Like