我知道 Rust 可以使用轻量级线程运行循环。就像是:
use task::spawn;
fn main() {
for 100.times {
do spawn {
io::println("Hello");
}
}
我怎么能在 D 中做到这一点?
我知道 Rust 可以使用轻量级线程运行循环。就像是:
use task::spawn;
fn main() {
for 100.times {
do spawn {
io::println("Hello");
}
}
我怎么能在 D 中做到这一点?
相关 API 文档:std.parallelism
以下是完成示例的几种方法:
并行 foreach,使用 TaskPool 的并行:
foreach (i, val; taskPool.parallel(new int[50])) {
writeln("Hello:", i);
}
常规 foreach,使用put将任务添加到任务池:
foreach (i; 0 .. 50) {
auto t = task!writeln("Hello:", i);
taskPool.put(t);
}
在新线程而不是 TaskPool中执行每个任务:
foreach (i; 0 .. 50) {
auto t = task!writeln("Hello:", i);
t.executeInNewThread();
}
Rust 的运行时有一个内置的任务调度器,但是对于 D,这是作为一个库来实现的。话虽如此,第二个在功能方面是最接近的,最后一个在语法方面是最接近的(但它们是操作系统线程,而不是轻量级的)。
在 D 中,轻量级线程由程序员显式控制。ATaskPool
类似于 Rust/Go 中的调度程序,但它为程序员提供了更细粒度的控制。这使它稍微冗长一些,但它也为您提供了map
、reduce
、foreach
等的并行版本。这使得更容易有效地表示更复杂的算法。
运行每个示例应该会给您预期的结果:乱序写入。
笔记:
从文档:
此池中的工作线程是守护线程,这意味着在终止主线程之前无需调用 TaskPool.stop 或 TaskPool.finish。
第二个示例不会等到所有工作人员都完成后,因此在测试中您可能不会得到任何结果(当 main 完成时,所有剩余的任务都被杀死)。您可能需要通过调用完成来阻止:
taskPool.finish(true);
D 没有针对轻量级线程的内置抽象。相反,您可以: