Combining Unique type with concurrency module
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Sep 13 17:11:07 PDT 2015
On 09/13/2015 09:09 AM, Alex wrote:
> I'm new to this forum so, please excuse me in advance for
> asking silly questions.
Before somebody else says it: There are no silly questions. :)
> struct std.typecons.Unique!(S).Unique is not copyable because it is
> annotated with @disable
I have made the code compile and work (without any thread
synchronization at all). See the comments with [Ali] annotations:
import std.stdio;
import std.concurrency;
import std.typecons;
void spawnedFunc2(Tid ownerTid)
{
/* [Ali] Aside: ownerTid is already and automatically
* available. You don't need to pass it in explicitly. */
receive(
/* [Ali] The compilation error comes from Variant, which
* happens to be the catch all type for concurrency
* messages. Unfortunately, there are issues with that
* type.
*
* Although implemented as a pointer, according to
* Variant, a 'ref' is not a pointer. (I am not sure
* whether this one is a Variant issue or a language
* issue.)
*
* Changing the message to a pointer to a shared
* object: */
(shared(Unique!S) * urShared)
{
/* [Ali] Because the expression ur.i does not work on
* a shared object, we will hack it to unshared
* first. */
auto ur = cast(Unique!S*)urShared;
writeln("Recieved the number ", ur.i);
}
);
send(ownerTid, true);
}
static struct S
{
int i;
this(int i){this.i = i;}
}
Unique!S produce()
{
// Construct a unique instance of S on the heap
Unique!S ut = new S(5);
// Implicit transfer of ownership
return ut;
}
void main()
{
Unique!S u1;
u1 = produce();
auto childTid2 = spawn(&spawnedFunc2, thisTid);
/* [Ali] Cast it to shared so that it passes to the other
* side. Unfortunately, there is no guarantee that this
* object is not used by more than one thread. */
send(childTid2, cast(shared(Unique!S*))&u1);
/* [Ali] We must wait to ensure that u1 is not destroyed
* before all workers have finished their tasks. */
import core.thread;
thread_joinAll();
writeln("Successfully printed number.");
}
Note that thread synchronization is still the programmer's responsibility.
> I'm aware of the fact, that my u1 struct can't be copied, but I don't
> intend to do so.
Correct.
> As in the docu stated, I want to lend the struct to the
> other thread (by using ref), being sure, that any other thread can't
> access the struct during it is processed by the first one.
There is a misconception. Unique guarantees that the object will not be
copied. It does not provide any guarantee that only one thread will
access the object. It is possible to write a type that acquires a lock
during certain operations but Unique isn't that type.
> Is such a thing possible?
> Thanks in advance.
> Alex
Ali
More information about the Digitalmars-d-learn
mailing list