Re: threads vs run-loops for keeping your GUI responsive
Re: threads vs run-loops for keeping your GUI responsive
- Subject: Re: threads vs run-loops for keeping your GUI responsive
- From: Greg Herlihy <email@hidden>
- Date: Fri, 09 Dec 2005 07:57:53 -0800
- Thread-topic: threads vs run-loops for keeping your GUI responsive
For a single-threaded app there is an inherent trade-off between responding
promptly to user events, and efficiently processing large amounts of data.
And while it is possible to "fine tune" a single threaded program's
behavior, it will never be possible for a single-threaded app to match the
responsiveness and throughput that it would have - were it multithreaded.
Here's the dilemma: a single thread must choose between checking for a user
event, or processing data. But how does it know which of these two options
it should be engaging in at any particular moment?
Let's recast the situation in more immediate terms. Imagine someone who
worked in an office where the phones did not ring. To answer one of these
silent phones, it is necessary to lift the receiver and check whether anyone
happens to be calling at that moment. Now anyone working in this office
would have a choice: they could spend their time picking up phone checking
for callers - thus ensuring responsiveness - or they could be doing other
work and check the phone only rarely - and thus ensure efficiency by
sacrificing responsiveness.
The problem with the silent phone would be solved if an office worker could
predict when a call would be coming in ahead of time. Similarly, if a single
threaded app could know in advance when the user was going to do something
at the computer, it could arrange to be waiting for that event as soon as it
came in. But since it is not yet possible to predict the future, neither
solution is practical.
Now imagine what happens when someone adds ringers to all of these silent
phones. Now a ring alerts the worker when someone is calling - they need not
spend any more time checking for calls. Under this new system, the ringing
phone will interrupt a person's work - but only for the duration of the call
- once the call ends, work resumes.
Now imagine which type of office (the one with silent phones or the one
whose phones ring) is likely to get more work done and which office is
likely to be more responsive to its customers.
A second thread provides much the same benefits for the app as a phone with
a ringer does to the office worker. It allows the app to spend the majority
of its cycles processing data worry-free. A user event - interrupts - its
task to let another thread handle the specifics of the user request. Once
done, the data processing can pick up right where it left off.
The somewhat paradoxical result is that the dual-threaded app is not only
more responsive - but it is also more efficient - completing the job in less
time than an equally responsive single-threaded app. It is able to do so,
by better prioritizing its time.
So if the responsiveness and throughput of the single threaded app is
acceptable as it stands, than it probably is not worthwhile to spend a lot
of time trying to improve its single-threaded efficiency. The upside is
limited. On the other hand, if its responsiveness and speed are not
currently adequate than offloading the data processing to another thread is
probably the only solution worth contemplating.
Should managing multiple threads turn out to be too much of a nuisance, then
moving the data processing to a different process entirely should also be
considered. The traditional UNIX model is to run dedicated, lightweight
tools for specific purposes. Tools that quit as soon as they are done.
Multiprocessing is a more modular and often more robust approach than
multithreading and certainly one that is easier to manage.
Greg
On 12/9/05 6:44 AM, "Niko Matsakis" <email@hidden> wrote:
>
Okay, I want to get away from the spinning beachball that inevitably
>
results when churning through a lot of data. I am writing a Core
>
Data app.
>
>
As a motivating example, I have an import function which reads in a
>
text file and creates corresponding objects. If the text file is
>
large, this can take quite a while. At the moment, I just create a
>
progress bar and update it: thus reassuring the user that something
>
is happening, but not really allowing them to do anything (such as,
>
say, cancel it).
>
>
Now, I know that I could create a parallel worker thread. The Cocoa
>
tools for doing so (performSelectOnMainThread:, detachThread:) are
>
quite nice. However, it seems like overkill for my task. Rather
>
than have to think about whether I have locked down access to my
>
NSManagedObjectContext, and whether or not some method is part of the
>
AppKit or not and therefore needs to happen on the main thread, I'd
>
rather just use a single-threaded approach.
>
>
It seems like what I really want to do is simply have a function
>
which does a discrete amount of work: processing one line from the
>
file, for example, and to repeatedly schedule calls of this function
>
onto the run loop. This way, if no other events should occur, my
>
function can get invoked, and I can do some work. Eventually, when
>
the work is done, I can exit the modal session as usual.
>
Transforming my code to work this way would be quite trivial.
>
>
Unfortunately, it is not clear to me how I might schedule a call to
>
this event. I have scoured the wiki and mailing list, but I can't
>
find much mention of this approach: everyone seems to want to create
>
worker threads.
>
>
I know I could use NSTimer, but again that doesn't feel quite right:
>
I want the function to be called ASAP, assuming that nothing else is
>
going on; scheduling it for a certain time seems overly complicated.
>
>
Surely there is a way to do this? Am I missing something? Is this
>
not a good approach?
>
>
>
Niko
>
_______________________________________________
>
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
_______________________________________________
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