From: Bill Kelly Date: 2003-10-31T16:45:25+09:00 Subject: Re: Trying to figure out thread safety Hi, From: > 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