Thread overview
question
Dec 13
fred
Dec 13
Basile B.
December 13

import core.thread;
import std.concurrency;
import std.stdio : w = writeln;

void w2(shared(bool) *done)
{
	while (*done == false)
	{
		Thread.sleep(100.msecs);
		w("print done? ", *done);
	}
}

void s2()
{
	shared(bool) isDone = false;
	spawn(&w2, &isDone);
	Thread.sleep(400.msecs);
	isDone = true;

}

void main()
{
	s2();
}

=========

a bug ?
thanks anyway

December 13

On Wednesday, 13 December 2023 at 12:49:14 UTC, fred wrote:

>

[...]
a bug ?
thanks anyway

Try to define the flag as static

static shared(bool) isDone = false;

I dont know if that should be a compiler error to have local shared (I tend to think yes as locals are specific to a frame, i.e a thread). At least you know how to fix the issue.

December 13

On Wednesday, 13 December 2023 at 12:49:14 UTC, fred wrote:

>

a bug ?

It helps if you explain what you're talking about so we don't have to guess.

I tried the code on my computer and it worked fine. But then figuring, you must be saying something doesn't work right, I tried it on another compiler and saw it endlessly loop.

So it ended using my dmd 2.098, looped on my dmd 2.105.... but this is actually just coincidence. Consider this:


void s2()
{
    shared(bool) isDone = false;
    spawn(&w2, &isDone);
    Thread.sleep(400.msecs);
    w("done");
    isDone = true;
}

The variable isDone is temporary; as a local variable, it ceases to exist when s2 returns. So when w2 tries to check if it is done or not, it takes a bit of luck for the memory to still be the same value as it was; it has likely been recycled or otherwise cleared by then.

You need to keep the variable alive until both threads are done with it, either by doing some fancy synchronization between the threads or just letting the garbage collector manage the shared variable:

    void s2()
    {
         // let the GC do it
        shared(bool)* isDone = new shared bool;
        spawn(&w2, isDone);
        Thread.sleep(400.msecs);
        w("done");
        *isDone = true;
    }