views:

450

answers:

5

In the main loop of a worker thread that has to poll to know if there's work to do, I let it sleep in order to not busy-wait. How do I determine a good length for sleeping? E. g. if I wake up every millisecond, it's probably useless to sleep at all. If I wake up every ten minutes, it might make the app look unresponsive (depending on what the thread is doing).

I've heard before what cadrian says below, that a human user won't notice timespans around 100 ms, but what about approaching it from the machine side? How small can the interval get before it starts to get wasteful?

I guess, it boils down to a more general (i. e. platform-independent) version of this question.

EDIT: Of course, the question should always be rephrased first as "How can I change this to the event pattern instead of polling", but let's assume for now that I can't or don't want to.

A: 

Let it sleep forever, waking it up when there's input available?

Inferis
+1  A: 

If another thread of the same app feeds your thread, then you should consider using an event pattern instead of polling. For example in Java you would use wait/notify.

Otherwise, if the app is user-oriented, a poll every 100ms or so should be more than enough. The user won't notice.

cadrian
A: 

You should be firing a signal to alert the thread. If you're using c, you can use something like a conditional variable from p-threads. If you're using something newer, like .NET you can use an EventWaitHandle. I'm sure java and other 4gl's have similar classes as the EventWaitHandle.

Nicholas Mancuso
Even in the first revision, I had ruled out event based waking up, but maybe it wasn't clear enough. I've now clarified the post.
Hanno Fietz
+1  A: 

Do you have an idea of how long the operation can take? Maybe a range? I'm assuming that your thread essentially does this:

while(!workComplete) {
  Thread.Sleep(n);
}

If it is a UI worker thread, as long as they have some kind of progress indicator, anywhere up to half a second should be good enough. The UI should be responsive during the operation since its a background thread and you definitely have enough CPU time available to check every 500 ms. This, of course, depends on how much responsiveness your UI needs. But remember, it is all about perceived performance when it comes to UI.

Another approach is an exponential backoff. Let's say you check after 200 ms whether the input has completed. If it has not, next time sleep for 400 ms. If after that time it has not completed, sleep for 800 ms. etc. You should make sure that after sometime you throw a TimeoutException so that you can avoid some looong sleeping.

siz
If you are going to downvote, please comment. I'd love to hear how this answer is wrong given what the poster is asking for.
siz
I'd say it's not at all wrong. But then I did upvote it, so I can't really explain anyway.
Hanno Fietz
+5  A: 

Sometimes polling is the answer.

However, how often it polls depends on what the thread is doing, so make it configurable.

We have threads that check for email. They can check external mail boxes, we only check the mailboxes every thirty seconds or so (but it's configurable). Each check is a call over the web, calling every second or 10th of a second would hammer the network, 30 seconds is ok, and it doesn't matter if the email isn't processed THE MOMENT it lands in the in box (however some customer sites check every 5 mintues).

We have other threads that poll for files in a folder, and/or for new requests added to a table in the database. These poll for work every 1 to 5 seconds (depending on what they're doing).

Now regardless of how long you wait between polling, we don't let any of our threads sleep for longer than a second. The reason being, if you try to stop a windows service that has a thread sleeping for 60 seconds, you could be waiting 60 seconds before the service stops.

If you need to bring a machine down in a hurry, a Rip Van Winkle thread will really twist your mellon.

So, have your polling intervals as far apart as you need, but don't sleep for much longer than a second.

Hope this helps

Binary Worrier
Thanks, that's very useful examples you have there.
Hanno Fietz
Also a good point that the polling and the sleeping are two separate things that might call for different intervals. I had not thought of bringing down the machine, and that's actually quite important in my app.
Hanno Fietz
Glad to be of help :)
Binary Worrier