我试图编写一个函数parallelize
,它将函数B
作为参数并返回一个函数C
,其中C
返回一个句柄一个运行B
的线程。我明白这可能是笨重或荒谬的;它主要是作为一个学习项目。更高级别的目标是在迭代器上实现并行映射函数,其中列表的每个元素将映射到不同的线程(或最终可能通过线程池)。我很快就意识到我已经超越了我的头脑。鉴于我所描述的,parallelize
的类型应该是什么?
答案 0 :(得分:7)
让我们逐步介绍:
一个函数
parallelize
fn parallelize() {
unimplemented!()
}
是的,这个功能还可以。
参数a函数B
我假设您希望能够返回某些内容的功能,因此我将使用泛型R
。
fn parallelize<B, R>(function: B)
where
B: FnOnce() -> R,
{
unimplemented!()
}
哦,哦。你can't do this cleanly in Rust yet。这意味着我们将返回盒装特征对象而不是返回一个函数C
fn parallelize<B, R>(function: B) -> Box<FnOnce()>
where
B: FnOnce() -> R,
{
unimplemented!()
}
其中C返回运行B
的线程的句柄
use std::thread::JoinHandle;
fn parallelize<B, R>(function: B) -> Box<FnOnce() -> JoinHandle<R>>
where
B: FnOnce() -> R,
{
unimplemented!()
}
这是你的签名。一切都在这里完成!
.....
当然,还有更多工作要做。例如,当线程实际上启动时,您没有说明。这意味着我可以选择,我选择最简单的方法 - 当调用者请求句柄时启动线程。
use std::thread::{self, JoinHandle};
fn parallelize<B, R>(function: B) -> Box<FnOnce() -> JoinHandle<R>>
where
B: Send + FnOnce() -> R + 'static,
R: Send + 'static,
{
Box::new(|| thread::spawn(function))
}
我猜你也可以立即开始:
use std::thread::{self, JoinHandle};
fn parallelize<B, R>(function: B) -> Box<FnOnce() -> JoinHandle<R>>
where
B: Send + FnOnce() -> R + 'static,
R: Send + 'static,
{
let handle = thread::spawn(function);
Box::new(|| handle)
}
我不知道为什么你做第二个;在这种情况下,你也可以直接返回句柄。如果您执行 ,您也可以直接致电thread::spawn
。
哦,我想我无法将那些额外的特质限制在你身边,是吗?在调用thread::spawn
时,你必须确保在线程退出之前没有传递给它的任何东西都会停止有效(因此'static
)并且在线程之间传输是安全的(因此Send
)。< / p>
更高级别的目标是在迭代器上实现并行映射函数
存在,称为Rayon。
另见: