Pause Self, Resume on Event

Sean Kelly sean at invisibleduck.org
Thu Jul 17 11:04:09 PDT 2008


dsimcha wrote:
> I'm trying to implement a low-overhead thread pool library that avoids busy
> waiting, and the issue I keep running into is, if a thread is waiting on a job
> in the pool queue, how to get the waiting thread to pause and then be resumed
> by the worker thread when the job is finished, w/o creating any race hazards.

Assuming you're using Tango, you should use a Condition:

class Task
{
     alias void delegate() Dg;
     Mutex m;
     Condition c;
     Dg[] queue;

     this()
     {
         m = new Mutex;
         c = new Condition;
         auto t = new Thread( &run );
     }

     void assignTask( Dg dg )
     {
         synchronized( m )
         {
             queue ~= dg;
             c.notify();
         }
     }

private:
     void run()
     {
         Dg dg;

         while( true )
         {
             synchronized( m )
             {
                 while( queue.length < 1 )
                     c.wait();
                 dg = queue[$ - 1];
                 queue = queue[0 .. $ - 1];
             }
             dg();
         }
     }
}

The pool above contains only one thread and is pretty basic, but you get 
the idea.  c.wait() above atomically unlocks the mutex and waits for 
c.notify() to be called, and then atomically re-locks the mutex before 
returning.  This is a classic producer-consumer algorithm.

> If I synchronize resumeWaiting, then the thread that called wait() goes to
> pause inside a mutex, and nothing can get access to my instance of Task to
> resume it.

See above.  Conditions are kind of a special case.  Don't use 
pause/resume in Thread--they're a deadlock waiting to happen.  They've 
been deprecated in Java for this reason, and I have no idea why they're 
exposed in Phobos.  It's a major mistake IMO.

>  Is there a standard solution to problems like this?

Condition variables.  See above :-)


Sean


More information about the Digitalmars-d-learn mailing list