6

我知道 Rust 可以使用轻量级线程运行循环。就像是:

use task::spawn;

fn main() {
  for 100.times {
    do spawn {
      io::println("Hello");
    }
  }

我怎么能在 D 中做到这一点?

4

2 回答 2

11

相关 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 中的调度程序,但它为程序员提供了更细粒度的控制。这使它稍微冗长一些,但它也为您提供了mapreduceforeach等的并行版本。这使得更容易有效地表示更复杂的算法。

运行每个示例应该会给您预期的结果:乱序写入。

笔记:

从文档:

此池中的工作线程是守护线程,这意味着在终止主线程之前无需调用 TaskPool.stop 或 TaskPool.finish。

第二个示例不会等到所有工作人员都完成后,因此在测试中您可能不会得到任何结果(当 main 完成时,所有剩余的任务都被杀死)。您可能需要通过调用完成来阻止:

taskPool.finish(true);
于 2013-03-09T10:10:44.410 回答
8

D 没有针对轻量级线程的内置抽象。相反,您可以:

  • 使用线程(参见std.concurrencystd.parallelism
  • 通过显式让步执行手动使用程和多任务
  • 使用诸如Vibe.d 之类的库,它使用纤程实现异步 I/O,并在阻塞操作上隐式让步
于 2013-03-09T10:16:27.907 回答