Follow-up questions on sample class ThreadSafeQueue
Christiaan Hofman
cmhofman at gmail.com
Wed May 16 01:37:47 PDT 2007
On 16 May 2007, at 2:32 AM, Duncan Champney wrote:
>
> On May 15, 2007, at 7:37 PM, Shawn Erickson wrote:
>
>> On 5/15/07, Duncan Champney <duncanc at aol.com> wrote:
>>> Chris,
>>>
>>> Thanks for the link to the ThreadSafeQueue post. It makes good sense
>>> to me to use NSConditionLock to manage shared access to a job queue.
>>>
>>> I have a couple of follow-up questions.
>>>
>>> I'm a little unclear on how the worker threads would use the
>>> ThreadSafeQueue. I would think the ThreadSafeQueue object's methods
>>> would run on the main thread, and the worker threads would call
>>> those
>>> methods using performSelectorOnMainThread.
>>
>> Why do you think that? The whole point of the class is to allow
>> multiple threads to utilize the same queue directly. That is why it
>> uses NSConditionLock to protect the data structure it manages.
>
> Shawn,
>
> Thanks for the reply. I'm still trying to wrap my head around the
> subtleties of multi-threading. I understand you now.
>
>>
>>> Also, I'm puzzled by a couple of lines in the method implementation.
>>> Why do the methods in -dequeue and -tryDequeue retain and
>>> autorelease
>>> the object from "elements" in the same call. Here's the line from
>>> tryDequeue:
>>>
>>> element = [[[elements objectAtIndex:0] retain] autorelease];
>>
>> That retains the objects and balances that retain with an
>> autorelease.
>> That ensures that the object will continue to exist at least until
>> sometime in the future when the current autorelease pool is released
>> (drained).
>>
>> Why is this done? Well the removeObjectAtIndex: message could result
>> in the "element" object being deallocated because the elements array
>> could be the last object holding a retain on "element".
>>
>>> The retain and autorelease calls would seem to cancel each other
>>> out.
>>
>> That is true but not immediately.
>>
>>> The retain call would increase the retain count for the object in
>>> "elements", and then the autorelease would immediately decrement it,
>>> for a net null effect.
>>
>> No autorelease doesn't immediately decrement the retain count. Review
>> the concept of NSAutoreleasePools.
>
> I just did what you suggested and read the description of
> NSAutoreleasePool VERY carefully.
>
> The point I didn't understand before was that only an app's main
> thread automatically releases objects in the autorelease pool (when
> deallocating the autoreleasePool on the next pass through the event
> loop.) Secondary threads don't release objects in their autorelease
> pools automatically - they have to deallocate their autorelease
> pools explicitly in order for the objects in the pool to be
> released. Here's the relevant text:
>
>
> NSAutoreleasePool objects are automatically created and
> destroyed in the main thread of applications based on the
> Application Kit, so your code normally does not have to
>
> deal with them. The Application Kit creates a pool at the
> beginning of the event loop and releases it at the end, thereby
> periodically releasing any autoreleased objects
>
> generated while processing events.
>
>
> Thus when you execute the example statement I gave before
>
> element = [[[elements objectAtIndex:0] retain] autorelease];
>
> from a secondary thread, the retain statement increments the retain
> count, but the autorelease only adds the object to the autorlease
> pool. Since the autorelease pool for a secondary thread isn't
> deallocated automatically, the objects listed don't get balancing
> release calls until the thread terminates or the autorelease pool
> is deallocated.
>
Yes, that's why you should always create/release an autorelease pool
on any secondary thread you create. For example by running the
runloop on the secondary thread like this:
NSAutoReleasePool *pool = nil;
BOOL didRun = YES;
while (shouldKeepRunning && didRun) {
[pool release];
pool = [[NSAutoReleasePool alloc] init];
didRun = [NSAutoreleasePool currentRunLoop]
runMode:NSDefaultRunnLoopMode beforeDate:[NSDate distantFuture];
}
[pool release];
Christiaan
More information about the MacOSX-dev
mailing list