Concurrency message passing

jfondren julian.fondren at gmail.com
Tue Aug 17 12:22:02 UTC 2021


On Tuesday, 17 August 2021 at 11:05:09 UTC, JG wrote:
> Hi
>
> I have a program with two threads. One thread produces data 
> that is put in a queue
> and then consumed by the other thread. I initially built a 
> custom queue to do this, but thought this should have some 
> standard solution in D? I looked at std.concurrency and thought 
> that message passing could be used. However, the problem is 
> that I get the following error.
>
> Error: static assert:  "Aliases to mutable thread-local data 
> not allowed."
>
> I am not sure how to solve this.

The error tells you what you can't do. You can do anything other 
than that. What you *should* do depends on what exactly you're 
trying to do. Here are some examples:

Sending shared mutable data:

```d
import std.concurrency, std.stdio, core.atomic;

void incr() {
     auto counts = receiveOnly!(shared(int)[]);
     foreach (ref n; counts)
         atomicOp!"+="(n, 1); // shared(int) can't just be +='d
     ownerTid.send(true);
}

void main() {
     shared(int)[] counts = [0, 0, 0]; // no issues passing this
     spawn(&incr).send(counts);
     receiveOnly!bool;
     writeln(counts);
}
```

Sending immutable data:

```d
import std.concurrency, std.stdio, std.typecons;

void greeter() {
     auto who = receiveOnly!(string);
     writeln("Hello, ", who);
}

void main() {
     char[] who = "John".dup; // mutable&thread-local, can't be 
sent
     spawn(&greeter).send(who.idup); // create immutable copy to 
send
}
```

Sending scalar data:

```d
import std.concurrency, std.stdio;

__gshared int[3] counts;

void incr() {
     auto indexes = receiveOnly!(int, int);
     foreach (ref n; counts[indexes[0] .. indexes[1]])
         n++;
     ownerTid.send(true);
}

void main() {
     spawn(&incr).send(1, 2);
     receiveOnly!bool;
     writeln(counts);
}
```


More information about the Digitalmars-d-learn mailing list