DMD 1.022 and 2.005 releases - what's wrong with threading?
downs
default_357-line at yahoo.de
Sun Oct 7 01:49:46 PDT 2007
David Brown wrote:
> This is certainly not what I would hope to ever find in a normal piece of
> threading code. Let's pretend I have condition variables (.NET style), and
> see what it looks like:
>
> void put(T t)
> {
> synchronized (this) {
> buffer ~= t;
> conditionSignal (this);
> }
> }
>
> void get(T t)
> {
> synchronized (this) {
> while (buffer.length == 0)
> conditionWait (this);
> auto res=buffer[0];
> buffer = buffer[1..$];
> return res;
> }
> }
>
> where conditionSignal and conditionWait are as defined by .NET or posix
> Pthreads (with the condition variable and mutex as part of each object).
> This can be implemented directly on top of both Windows and Linux, meaning
> it won't hurt performance. It's a whole lot easier to use correctly, and
> doesn't obscure the code quite as much. (Yes, the conditionWait is inside
> of the synchronized, it is _required_ to be there, that's why it is so much
> easier to use). In fact, if a thread was allowed to 'pause()' itself
> inside of a synchronized section and that meant it would atomically release
> the critical section and pause, and then regain the critical section on
> resume, the Phobos version could be made much simpler.
>
> Other implementations using semaphores aren't much more difficult.
>
> I still would say this is too primitive for most uses, and higher level
> constructs can be made. But, only the useful primitives need to be in the
> thread library itself.
>
> David
Okay, let's try this again.
I'm not sure if the following code will work, seeing as I never actually
tested it. I'm fairly optimistic though ^^
module test4;
import std.thread;
class Lock
{
private
{
Thread locked;
bool[Thread] sleeping;
bool signalling=false;
}
void lock(Object what)
{
while (locked !is Thread.getThis) synchronized(what)
if (!locked) locked = Thread.getThis;
}
void unlock()
in
{
assert (Thread.getThis is locked);
}
body
{
locked = null;
}
void synchronize(Object what, void delegate() dg)
{
lock(what);
scope(exit) unlock;
dg();
}
void conditionWait(Object what)
{
synchronized(this) sleeping[Thread.getThis]=true;
unlock;
// prevent accidental resume
while (!signalling) Thread.getThis.pause;
synchronized(this) sleeping.remove(Thread.getThis);
lock(what);
}
void conditionSignal()
{
synchronized(this)
{
signalling=true;
scope(exit) signalling=false;
foreach (thr, bogus; sleeping) thr.resume;
}
}
}
class UnBoundedBuffer(T) {
private T[] buffer;
Lock lock; this() { lock=new Lock; }
void put(T t)
{
lock.synchronize(this, {
buffer ~= t;
lock.conditionSignal;
});
}
T get()
{
T res=void;
lock.synchronize(this, {
while (!buffer.length)
lock.conditionWait(this);
res = buffer[0];
buffer=buffer[1..$];
});
return res;
}
}
void main() {
auto bb=new UnBoundedBuffer!(int);
}
More information about the Digitalmars-d
mailing list