Does anyone understand how to use "shared" types with concurrency send/receive functions?
Steven Schveighoffer via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Aug 15 06:53:05 PDT 2017
On 8/14/17 5:27 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Monday, August 14, 2017 15:22:23 Steven Schveighoffer via Digitalmars-d-
> learn wrote:
>> On 8/13/17 11:40 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
>>> On Saturday, August 12, 2017 18:57:44 Arek via Digitalmars-d-learn
> wrote:
>>>> I have the folowing problem:
>>>> I like to envelope the class object in struct to control the
>>>> destruction moment and then send this object to another
>>>> thread/fiber (or task, cause I use vibe-d).
>>>>
>>>> I can't find any method to make it working. Any ideas?
>>>
>>> Unfortunately, send and receive do not currently work with shared
>>> because of issues with Variant, which they use internally.
>>
>> This can't be a correct statement. This is the whole point of shared.
>
> What's incorrect about it? It's a longstanding issue that because Variant
> can't contain shared data, send and receive do not work with shared.
The implementation details aren't important. From the documentation (and
no, this documentation is not wrong):
From spawn:
args must not have unshared aliasing. In other words, all arguments to
fn must either be shared or immutable or have no pointer indirection.
This is necessary for enforcing isolation among threads.
From send:
As with std.concurrency.spawn, T must not have unshared aliasing.
So clearly passing shared pointers or things containing shared pointers
should work fine.
As I was building code to test, I found that it does actually work for
shared int pointers:
import std.concurrency;
import std.typecons;
import std.stdio;
import core.thread;
void threadfunc()
{
bool done = false;
while(!done)
{ receive(
(shared(int)*foo) {*foo = 5; done = true;},
(Variant v) {}
);
}
}
shared int f;
void main()
{
auto tid = spawn(&threadfunc);
tid.send(&f);
Thread.sleep(1.seconds);
writeln(f);
}
No error, completes as expected, and outputs 5.
So it looks like this is really a straight up bug and has nothing to do
with the shared type qualifier. It is documented as working, and does
work in some cases.
I think if the shared item is not a reference, it is doing something
different, and this is incompatible with something in the
implementation. Indeed, if you attempt to send unshared references, you
get an assert. However, if you send a shared int (not a pointer), you
get a bunch of compiler errors. Clearly the implementation expects it to
work, as it doesn't fail the logical checks.
-Steve
More information about the Digitalmars-d-learn
mailing list