I know that Rust can run loops with lightweight threads. Something like:
use task::spawn;
fn main() {
for 100.times {
do spawn {
io::println("Hello");
}
}
How I can do this in D?
Relevant API doc: std.parallelism
Here are a few of ways of accomplishing your example:
Parallel foreach, using a TaskPool's parallel:
foreach (i, val; taskPool.parallel(new int[50])) {
writeln("Hello:", i);
}
Regular foreach, adding tasks to a task pool using put:
foreach (i; 0 .. 50) {
auto t = task!writeln("Hello:", i);
taskPool.put(t);
}
Execute each task in a new thread instead of a TaskPool:
foreach (i; 0 .. 50) {
auto t = task!writeln("Hello:", i);
t.executeInNewThread();
}
Rust's runtime has a built-in task scheduler, but with D, this is implemented as a library. That being said, the second is the closest in terms of functionality, and the last is the closest in terms of syntax (but they're OS threads, not lightweight).
In D, lightweight threads are explicitly controlled by the programmer. A TaskPool
is analogous to the scheduler in Rust/Go, but it gives more fine-grained control to the programmer. This makes it slightly more verbose, but it also gives you parallel versions of map
, reduce
, foreach
, etc. This makes it easier to represent more complex algorithms efficiently.
Running each example should give you the expected result: out of order writes.
Note:
From the doc:
The worker threads in this pool are daemon threads, meaning that it is not necessary to call TaskPool.stop or TaskPool.finish before terminating the main thread.
The second example doesn't wait until all workers are done, so in testing you may get no results (when main finishes, all remaining tasks are killed). You may need to block by calling finish:
taskPool.finish(true);
D has no built-in abstractions for lightweight threads. Instead, you can:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With