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