Threading challenge: calculate fib(45) while spinning
Sebastiaan Koppe
mail at skoppe.eu
Sat Oct 16 15:35:42 UTC 2021
On Friday, 15 October 2021 at 03:35:44 UTC, jfondren wrote:
> The book, "The Go Programming Language" has this simple
> goroutine example:
>
> [...]
Here is a similar implementation using the concurrency library:
```d
import concurrency;
import concurrency.stream;
import concurrency.sender : justFrom;
import concurrency.operations : via, race;
import concurrency.thread : ThreadSender;
import core.time : msecs;
import std.stdio : writef, writefln, stdout;
import core.thread : Thread;
void main() @safe {
enum chars = `-\|/`;
auto spinner = infiniteStream(0)
.scan((int acc, int _) => acc + 1, 0)
.collect((int i) shared @trusted {
writef("\r%c", chars[i % chars.length]);
stdout.flush();
Thread.sleep(100.msecs);
})
.via(ThreadSender());
enum n = 45;
auto work = justFrom(() => fib(n));
auto result = race(spinner, work).syncWait.value;
writefln("\rFibonacci(%d) = %d", n, result.get);
}
int fib(int x) pure @safe @nogc {
if (x < 2)
return x;
return fib(x - 1) + fib(x - 2);
}
```
Go has language support so it is a bit unfair to compare it.
But this code will properly handle errors (in case `writef` or
`flush` throws), and as well as having an explicit
synchronization point so that the final `writeln` is always after
the spinner is done.
More information about the Digitalmars-d-learn
mailing list