6

Rustは軽量スレッドでループを実行できることを私は知っています。何かのようなもの:

use task::spawn;

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

Dでこれを行うにはどうすればよいですか?

4

2 に答える 2

11

関連する API ドキュメント: std.parallelism

あなたの例を達成する方法のいくつかを次に示します。

TaskPool のparallelを使用した並列 foreach :

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 ではこれをライブラリとして実装しています。そうは言っても、2 番目は機能の点で最も近く、最後のものは構文の点で最も近いです (ただし、これらは OS スレッドであり、軽量ではありません)。

D では、軽量スレッドはプログラマによって明示的に制御されます。ATaskPoolは Rust/Go のスケジューラーに似ていますが、プログラマーにより細かい制御を提供します。これにより、少し冗長になりますがmapreduceforeach、 などの並列バージョンも提供されます。これにより、より複雑なアルゴリズムを効率的に表現しやすくなります。

各例を実行すると、期待どおりの結果が得られるはずです。順不同の書き込みです。

ノート:

ドキュメントから:

このプールのワーカー スレッドはデーモン スレッドです。つまり、メイン スレッドを終了する前に TaskPool.stop または TaskPool.finish を呼び出す必要はありません。

2 番目の例では、すべてのワーカーが完了するまで待機しないため、テストでは結果が得られない場合があります (メインが終了すると、残りのすべてのタスクが強制終了されます)。finishを呼び出してブロックする必要がある場合があります。

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

D には、軽量スレッド用の組み込みの抽象化がありません。代わりに、次のことができます。

  • スレッドを使用する ( std.concurrencyおよびstd.parallelismを参照)
  • ファイバーを使用し、明示的に実行を譲ることによって手動でマルチタスクを実行します
  • Vibe.dなどのライブラリを使用します。これは、ファイバーを使用して非同期 I/O を実装し、ブロック操作で暗黙的な譲歩を行います。
于 2013-03-09T10:16:27.907 に答える