Concurrency Confusion
John Colvin via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Aug 4 01:36:25 PDT 2015
On Tuesday, 4 August 2015 at 08:03:54 UTC, 岩倉 澪 wrote:
> Hi all, I'm a bit confused today (as usual, haha).
>
> I have a pointer to a struct (let's call it Foo) allocated via
> a C library.
> I need to do some expensive computation with the Foo* to create
> a Bar[], but I would like to do that computation in the
> background, because the Bar[] is not needed right away.
>
> I definitely do not want there to be a copy of all elements of
> the Bar[] between threads, because it is very large.
>
> I tried to implement it like this:
>
> void fooPtrToBarArr(in shared Foo* f, out shared Bar[] b){
> /*do work*/ }
> __gshared Foo* foo;
> foo = allocateFoo();
> __gshared Bar[] bar;
> spawn(foo, bar);
>
> To my dismay, it results in a cryptic compiler error:
>
>> template std.concurrency.spawn cannot deduce function from
>> argument types
>> !()(void function(shared(const(Foo*)) f, out shared(Bar[]) b),
>> Foo*,
>> Bar[]), candidates are:
>> /usr/include/dlang/dmd/std/concurrency.d(466):
>> std.concurrency.spawn(F, T...)(F fn, T args) if
>> (isSpawnable!(F, T))
>
> Any help would be greatly appreciated :)
Do you mean this instead?
spawn(&fooPtrToBarArr, foo, bar);
Anyway, you need to use shared, not __gshared, then it should
work. E.g.
import std.concurrency;
struct Foo{}
auto allocateFoo() { return new Foo(); }
struct Bar{}
void fooPtrToBarArr(in shared Foo* f, out shared Bar[] b){
/*do work*/ }
void main()
{
shared Foo* foo = cast(shared)allocateFoo();
shared Bar[] bar;
spawn(&fooPtrToBarArr, foo, bar);
}
Then you will have to cast away shared to make use of bar in your
normal code (or continue using it as shared, but that would be
frustrating). To totally avoid any ordering concerns, you could
put a full mfence in before casting away shared
(http://dlang.org/phobos/core_atomic.html#.atomicFence).
More information about the Digitalmars-d-learn
mailing list