我如何保证一个线程将比另一个线程更长,允许我在没有“静态”的情况下共享引用?

时间:2018-04-17 16:05:15

标签: multithreading rust thread-safety

我正在研究Rust中的任务调度框架,它使用执行程序之间的工作窃取。每个执行程序都有自己的线程,我使用如下代码生成它:

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

抽象地说,必须有一种方法让这个线程能够看到其他线程的工作队列并对该队列执行窃取操作。

我现在正在这样做的方法是将一个函数(Fn())传递给结构的new方法on_steal,该方法通过借用vec<Stealer>来关闭

Rust在两个地方对我大喊:

  • 首先,它需要on_steal的生命周期参数,特别是它要求static
  • on_steal祝福'static后,我借用vec<Stealer>的生命周期就成了问题。

我目前的解决方案是将vec<Stealer>包裹在Arc<mutex<_>>中,这很好。但我想知道是否有一个更优雅的解决方案来指定Rust中线程的生命周期参数。

我希望表达某种线程将比另一个线程更长的保证,从而允许我将更长寿的线程的引用借给更短的线程而不要求那些引用是静态的。

1 个答案:

答案 0 :(得分:0)

没有简单的方法可以做到这一点。

传递给F的任何thread::spawn必须为'static;你不能在线程上断言生命周期,或者将它绑定到特定的范围;您提供的功能必须是静态的,因此您无法为此目的使用具有自定义生命周期的闭包。

解决这个问题的方法是unsafe所有事情;这里有两个典型的例子:

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

实际上,没有更多的优雅&#39;解决方案而不仅仅是使用Arc。您也可以尝试使用频道协调,使用现有的解决方案,如scoped_threadpool或编写自己的解决方案,但我强烈建议不要重新发明轮子并使用不安全的方式编写自己的实现,它很容易搞砸。

我个人认为Is it possible to send closures via channels?之类的东西适合你的目的,但没有更多细节,很难知道。