[Solved] Re: Synchronizing Thread Execution
[Solved] Re: Synchronizing Thread Execution
- Subject: [Solved] Re: Synchronizing Thread Execution
- From: Antonio Nunes <email@hidden>
- Date: Wed, 6 Dec 2006 11:55:45 +0000
On 5 Dec 2006, at 03:52, Chris Suter wrote:
My suggestion of using @synchronized (@"MyThreadLock") will not
work if you use it in more than one place.
I *was* using it in only one place, namely in the actual conversion
method. It had not occurred to me to synchronize the drawing routine
and the background thread routine using @synchronized since I hadn't
realized that it could be used thus. Nonetheless, whatever I used as
argument to @synchronized I could not get it to work as needed, i.e.
that the method would only be entered once at a time for the document
(or the app). (I wasn't maybe clear enough in my original post, but
the synchronization needs to be document level, not global.) At best
it would block re-entry of the object.
However, the other suggestions should work fine:
static NSString *syncObject = @"MyConversionSyncObject";
From the helper thread:
while ((sourceObject = [e nextObject]) && !_isSaving && !
_isClosing) {
…
if ([sourceObject owner]) {
@synchronized (syncObject) {
[sourceObject convertCacheToPDFDoc];
}
}
}
From drawRect:
@synchronized (syncObject) {
// Draw the required sheets
for (i = firstSheetSideIndex; i < lastSheetSideIndex; i++) {
sheetSide = [self objectInSheetSidesAtIndex:i];
[sheetSide drawWithShadow:[document showsSheetBreaks] && [ctx
isDrawingToScreen]];
}
}
That works like a charm. Now only one object is ever converted at a
time, and the PDFDocument object is never re-entered. The only change
I made to the above, since I need to scope the synchronization
document-wide rather than application-wide, was to instantiate the
syncObject in the NSDocument's init method thus:
conversionSyncObject = [[NSObject alloc] init];
… and use that as the argument to @synchronized. (That's easier than
creating a string unique to the document, and using a compile time
defined string synchronizes the blocks application wide which is
overkill and decreases efficiency.)
I tested this with several documents open at the same time, each
converting and redrawing simultaneously, and the results were great.
The only (?) pitfall with this, I think, is that it is possible to
change conversionSyncObject elsewhere in the code, opening up the
possibility of a short-lived (yet potentially disastrous) de-
synchronisation of the threads. But I don't know how to make the
conversionSyncObject ivar immutable once it has been assigned . Any
pointers to that would be greatly appreciated.
I would add that I'm not sure that you want to be blocking the
drawing thread whilst conversion takes place since presumably the
conversion could be a lengthy process, but without knowing more
about what you're trying to do, I can't say for sure. A better
approach would be to use some kind of message passing (that could
be a queue, performSelectorOnMainThread, or via flag variables)
between the two threads which would minimise blocking.
Yes, that's a very valid concern. Timings show though that the
conversion is never lengthy on a human scale. The main thread is
never blocked for any considerable length of time. I don't think the
lag due to a conversion being in progress when drawRect is called is
ever bigger than 500ms (although the total lag the user experiences
can be much longer depending on how many pages have to be redrawn,
but that is true even when the conversion has finished, and is due to
the inherent slowness of drawing PDF pages to the screen).
The real solution to the issue will be in a restructuring of the
code, which will solve a number of problems that exist with the
current way pages are stored, and which should do away with the need
to perform the conversion at all. But for the problem at hand it
looks like we have a working solution.
My gratitude to everyone who contributed to this thread.
-António
----------------------------------------------------
A merry heart does good like medicine
----------------------------------------------------
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden