Combining Unique type with concurrency module
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Sep 14 01:08:34 PDT 2015
On 09/14/2015 12:07 AM, Alex wrote:
> Do you have a hint how to create such a type? The needed operation is
> "onPassingTo" another thread. So the idea is to create a resource, which
> is not really shared (a question of definition, I think), as it should
> be accessible only from one thread at a time.
> But there is a "main" thread, from which the resource can be lent to
> "worker" threads and there are "worker" threads, where only one worker
> can have the resource at a given time.
Here is an unpolished solution that enforces that the thread that is
using it is really its owner:
struct MultiThreadedUnique(T) {
Tid currentOwner;
Unique!T u;
this(Unique!T u) {
this.u = u.release();
this.currentOwner = thisTid;
}
void enforceRightOwner() {
import std.exception;
import std.string;
enforce(currentOwner == thisTid, format("%s is the owner; not %s",
currentOwner, thisTid));
}
ref Unique!T get() {
enforceRightOwner();
return u;
}
void giveTo(Tid newOwner) {
enforceRightOwner();
currentOwner = newOwner;
}
}
The entire program that I tested it with:
import std.stdio;
import std.concurrency;
import std.typecons;
void spawnedFunc2(Tid ownerTid)
{
receive(
(shared(MultiThreadedUnique!S) * urShared)
{
auto ur = cast(MultiThreadedUnique!S*)urShared;
writeln("Recieved the number ", ur.get().i);
ur.giveTo(ownerTid);
}
);
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;
}
struct MultiThreadedUnique(T) {
Tid currentOwner;
Unique!T u;
this(Unique!T u) {
this.u = u.release();
this.currentOwner = thisTid;
}
void enforceRightOwner() {
import std.exception;
import std.string;
enforce(currentOwner == thisTid, format("%s is the owner; not %s",
currentOwner, thisTid));
}
ref Unique!T get() {
enforceRightOwner();
return u;
}
void giveTo(Tid newOwner) {
enforceRightOwner();
currentOwner = newOwner;
}
}
void main()
{
MultiThreadedUnique!S u1 = produce();
auto childTid2 = spawn(&spawnedFunc2, thisTid);
u1.giveTo(childTid2);
send(childTid2, cast(shared(MultiThreadedUnique!S*))&u1);
import core.thread;
thread_joinAll();
writeln("Successfully printed number.");
auto u2 = &u1.get();
}
Ali
More information about the Digitalmars-d-learn
mailing list