Re: Am I using NSConditionLock correctly?
Re: Am I using NSConditionLock correctly?
- Subject: Re: Am I using NSConditionLock correctly?
- From: Steve Weller <email@hidden>
- Date: Mon, 10 Oct 2005 14:57:19 -0700
On Oct 10, 2005, at 1:37 PM, jkp wrote:
The way you have described it, you are making your main thread
sleep on the condition lock whilst your worker does the
work...blocking in the process. the simple question i ask you
is...what does this buy you?
My main thread has to wait for the worker thread to get into a known
state so I can save my objects to disk. So I need to block my main
thread until the worker thread says "I've stopped now". It is a short
amount of time -- short enough that the interface will not suffer
during the block.
You might as well just do the calculation on the main thread and
simplify your life! If you have the main thread sleep on the lock
whilst the worker does its work you are still blocking, so you
achieve the same thing.
The main thread keeps the GUI alive, so it cannot sleep under normal
circumstances. And this whole project is an exercise in using a
computationally-intensive worker thread.
I recently implemented worker class to use throughout my current
application and i learnt a lot in the process. A condition lock is
a great way to go since it allows you to have your workers sleep
efficiently and for you to exact granular control on them when you
need their services.
The way you describe is interesting. I am currently starting and
stopping my worker thread by creating and destroying it. But I have
reasons for doing that: I need to be able to throw away its state and
give it a new state to continue calculating with. It's easier to
throw away the whole thread and start a new one. I can see how
condition locks can be used to signal a thread what to do and read
its state back.
I think you could do with defining a set of conditions that might
apply to your thread at any point during its life cycle. Maybe
something like NOWORK, WORKPENDING, DATAPENDING etc...You can use
these to notify the worker what it needs to do. The worker can do
its thing and when it is done you have a choice of ways to send
data / notify the main thread that things are finished. My
favorite is NSObject's
performSelectorOnMainThread:withObject:waitUntilDone: method. You
can use this to call a routine on the main thread and if you want,
wait until it is finished before your worker continues on its way.
This way your main thread can carry on accepting user input etc,
but each time it returns to its runloop it gets a chance to process
a pending request from the worker to perform a selector.
I use that to update my GUI: progress bars etc. and to avoid having
to lock umpteen things. But I am actually finding the synchronous
nature of the call limiting. Not only that but async calls to main
thread methods are secretly synced up somewhere to, so thwarting some
other things I have tried.
Another way you could do it would be to use the condition lock to
signal you have data, and maybe use a timer to check the lock from
the main thread - again, this way you dont lock the main thread,
but when the timer fires and there is data, the main thread does
the right thing. I dont like this method myself since it is
basically polling, but that would be one way you could use the
condition lock in this way if you wanted to.
Yes, I am desperately trying to avoid poll/sleep, but may have to go
that way if all else fails.
These are just some thoughts and ideas, but i think you could do
with working out exactly what you want your worker thread
implementation to be capable of, and then perhaps write a small
test app that proves that it can do these things as you want. I'd
also take time to stress test the classes you write since you will
be suprised what problems can arrise that you hadnt thought of.
I'm guilty of lack of design forethought and experimentation. But
with good reason: I have no thoughts to put in the fore, since I am
learning this as I go along, and for experimentation: this is it.
If its any comfort it took me 3 iterations to get a pair of classes
that do the job for me and that i am happy with. Multithreading is
a tough topic so dont be suprised if you need to go back and rehash
your design several times before you get something that works for you.
I'm on number three right now I think. What surprises me is that
multithreading is much harder than multiprocessing and/or reentrant
interrupt-driven code. It's slippery, but not entirely so.
My next attempt is to do exactly what I have been doing but with a
global (static) lock. This should circumvent all the swizzling and
whatever is syncing for me I hope.
HTH
Jamie
PS - I in no way claim to be an expert on this subject, im just
sharing my experiences with you.
On 10 Oct 2005, at 06:53, Steve Weller wrote:
I am using NSConditionLock to delay the completion of a method
while another thread completes. I am not sure that I am using it
correctly, since my conditional lock hangs up the program.
In my worker thread I do [calculatingLock lock]; [calculatingLock
unlockWithCondition:YES] when calculation starts and
[calculatingLock lock]; [calculatingLock unlockWithCondition:NO]
when it stops.
In my method that depends on the worker thread stopping I do
[calculatingLock lockWhenCondition:NO]; [calculatingLock
unlockWithCondition:NO]. The idea is that it should wait for the
condition to be set to NO before continuing. It hangs at this
point. If this is all correct then my problem lies elsewhere.
More information on my blog, URL below.
--
Watch me learn Cocoa http://homepage.mac.com/bagelturf/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40kirkconsulting.co.uk
This email sent to email@hidden
--
Watch me learn Cocoa http://homepage.mac.com/bagelturf/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden