On 10/14/21 11:35 PM, jfondren wrote:
The book, "The Go Programming Language" has this simple goroutine example:

```go
func main() {
     go spinner(100 * time.Millisecond)
     const n = 45
     fibN := fib(n) // slow
     fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
}

func spinner(delay time.Duration) {
     for {
         for _, r := range `-\|/` {
             fmt.Printf("\r%c", r)
             time.Sleep(delay)
         }
     }
}

func fib(x int) int {
     if x < 2 {
         return x
     }
     return fib(x-1) + fib(x-2)
}
```

Attempt #1, with std.concurrency:

```d
import std.concurrency : spawn;
import core.thread : Thread;
import std.stdio : writefln, writef, stdout;
import std.datetime : msecs, Duration;

void main() @safe {
     (() @trusted { spawn(&spinner, 100.msecs); })();
     const n = 45;
     const fibN = fib(n); // slow
     writefln!"\rFibonacci(%d) = %d"(n, fibN);
}

void spinner(Duration delay) @safe {
     (() @trusted { Thread.getThis.isDaemon(true); })();
     while (true) {
         foreach (char c; `-\|/`) {
             writef!"\r%c"(c);
             (() @trusted { stdout.flush; })();
             (() @trusted { Thread.sleep(delay); })();
         }
     }
}

int fib(int x) pure @safe @nogc {
     if (x < 2)
         return x;
     return fib(x - 1) + fib(x - 2);
}
```

This version has two problems:

1. a race condition with `isDaemon`: if `main()` ends before `isDaemon(true)` is called, then the program never ends because the kill-non-daemon-threads module destructor is called while the new thread isn't a daemon thread.

You can also just spawn a thread directly with `Thread`, which I believe allows you to set the daemon-ness from `main`.


2. it crashes about 10% of the time on exit (in dmd, gdc, and ldc). valgrind on a gdc build complains about "Conditional jump or move depends on uninitialised value(s)" early on.


The crash is likely because you are using D i/o utilities, and the runtime is shut down. Technically it shouldn't cause a problem, but possibly there are things that are needed deep inside `writef`.

If you switch to `printf`, it will probably work.

-Steve

Reply via email to