Hi,

From: <agemoagemo / yahoo.com>

> Basically, I'm going to have some objects. Only one
> thread should access an object at a time, and each
> thread will only access one object at a time. I'd like
> to be able to put something in the object that a
> thread can call on, which will allow the thread to
> continue when the object is available, and then the
> thread can release the object so other threads can use
> it.
> 
> This doesn't seem quite appropriate to use a mutex,
> and ConditionVariable, which sounds like it's doing
> something similar, is always used within a mutex.
> Also, a thread shouldn't wait until a something else
> sends a signal - unless some other thread has
> specifically asked for the object, it should execute
> immediately.

A mutex sounds to me - if I understand correctly what
you've described - like a pretty good fit for your 
situation.

I'm not so sure I apprehend your intentions with one
thread only accessing one object at a time, and each...
OK... Do you really require that?  It sounds like you're
saying you have a pool of objects, and many threads.
You want /only/ one object in the pool to be able to be
utilized at /any/ given time by the whole collection of
threads?

That doesn't sound right.  Possibly you mean each thread
can grab an object from the pool, and send messages to
it, so long as no two threads are simultaneously accessing
the /same/ object from the pool?

In any case let's start with the Mutex as a locking
mechanism to serialize access to any given object instance.

------------------------------------------------------
require 'thread'

class ThreadSavvy
  def initialize
    @mutex = Mutex.new
    @happy = true
  end

  def do_work
   # @mutex.synchronize {
      was_happy = @happy
      puts(was_happy ? "Happy!" : "Not happy!")
      @happy = false
      sleep 0.25
      @happy = was_happy
   # }
  end
end

$inst = ThreadSavvy.new

thr = []
0.upto(9) do
  thr << Thread.new do
    10.times { $inst.do_work }
  end
end

thr.each {|t| t.join }

------------------------------------------------------

If you run the above with the @mutex.synchronize block
commented out, as above, you should see quite a bit
of unhappiness. :)  With the synchronize block everything
should be completely and positively ebullient.

We have 10 threads all trying to do_work on a single
global object instance.  The requests to do_work are
serialzied using the mutex synchronize block so that
only one thread may be doing work on that instance at
once.

ConditionVariables, on the other hand, come into play
when we want to be notified when someone has completed
some work.  Mutexes are about 'doing', ConditionVariables
are about 'receiving'... Sort of .. :)

Hope this helps  ( ?  )

Regards,

Bill