0

I'm working on a task scheduling framework in Rust that uses work stealing between executors. Each executor has it's own thread which I have spawned using code that looks like this:

let t_handle = thread::spawn(move || {...}

Abstractly, there must be a way for this thread to be able to see the work queues of other threads and perform a stealing operation on that queue.

The way I'm doing this right now is by passing a function (Fn()) into the struct's new method called on_steal which closes over a borrow of vec<Stealer>.

Rust yells at me in two places:

  • First it wants a lifetime parameter for on_steal, and specifically it's asking for static.
  • After blessing that on_steal with 'static, the lifetime for my borrow of vec<Stealer> becomes an issue.

The solution I have currently is to wrap my vec<Stealer> in a Arc<mutex<_>>, which is fine. But I'm wondering if there is a more elegant solution for specifying lifetime params of threads in Rust.

I'm looking to express some kind of guarantee that one thread will outlive another, thus allowing me to lend out references from the more longevous thread to the shorter lived thread without requiring those refs to be static.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
aaronlangford31
  • 104
  • 1
  • 6
  • 2
    Please provide a [MCVE] or your current solution. It's much better to have some code than to make guesses. – E_net4 Apr 17 '18 at 16:11
  • 1
    Have you seen [Rayon](https://crates.io/crates/rayon): *Simple work-stealing parallelism for Rust* – Shepmaster Apr 17 '18 at 16:24
  • 2
    I believe your question to be answered by the answers in [Lifetime troubles sharing references between threads](https://stackoverflow.com/q/28654978/155423), [How can I pass a reference to a stack variable to a thread?](https://stackoverflow.com/q/32750829/155423), and [How do I share a generic struct between threads using Arc>>?](https://stackoverflow.com/q/40035731/155423). If you disagree, please [edit] your question to explain the differences (in addition to providing a MCVE). – Shepmaster Apr 17 '18 at 16:29
  • Look for scoped threads and scoped threadpools – CodesInChaos Apr 17 '18 at 18:11

1 Answers1

0

There is no trivial way to do this.

Any F passed to thread::spawn must be 'static; you cannot assert a lifetime on the thread, or bound it to a specific scope; the function you supply must be static, so you cannot use a closure with a custom lifetime for this purpose.

The work around for this is to unsafe all the things; here are two typical examples:

https://github.com/Kimundi/scoped-threadpool-rs/blob/master/src/lib.rs#L209

https://github.com/crossbeam-rs/crossbeam-utils/blob/master/src/scoped.rs#L326

Practically speaking, there is no significantly more 'elegant' solution than just using Arc. You could also try coordinating using channels, using an existing solution like scoped_threadpool or write your own, but I strongly advise against re-inventing the wheel and writing your own implementation using unsafe, its very easy to mess up.

Personally, I think something like Is it possible to send closures via channels? would suit your purpose, but without more details, its hard to know.

Doug
  • 32,844
  • 38
  • 166
  • 222