tags:

views:

693

answers:

4

I am writing an queue processing application which uses threads for waiting on and responding to queue messages to be delivered to the app. For the main part of the application, it just needs to stay active. For a code example like:

while True:
  pass

or

while True:
  time.sleep(1)

Which one will have the least impact on a system? What is the preferred way to do nothing, but keep a python app running?

+4  A: 

I've always seen/heard that using sleep is the better way to do it. Using sleep will keep your Python interpreter's CPU usage from going wild.

hernan43
Yup, makes sense!
Crad
+9  A: 

I would imagine time.sleep() will have less overhead on the system. Using pass will cause the loop to immediately re-evaluate and peg the CPU, whereas using time.sleep will allow the execution to be temporarily suspended.

EDIT: just to prove the point, if you launch the python interpreter and run this:

>>> while True:
...     pass
...

You can watch Python start eating up 90-100% CPU instantly, versus:

>>> import time 
>>> while True:
...     time.sleep(1)
...

Which barely even registers on the Activity Monitor (using OS X here but it should be the same for every platform).

Jay
Thanks, I figured that was the case, but I kept seeing pass in documentation.
Crad
+6  A: 

You don't give much context to what you are really doing, but maybe Queue could be used instead of an explicit busy-wait loop? If not, I would assume sleep would be preferable, as I believe it will consume less CPU (as others have already noted).

[Edited according to additional information in comment below.]

Maybe this is obvious, but anyway, what you could do in a case where you are reading information from blocking sockets is to have one thread read from the socket and post suitably formatted messages into a Queue, and then have the rest of your "worker" threads reading from that queue; the workers will then block on reading from the queue without the need for neither pass, nor sleep.

Johan
Thanks for the tip on Queue looks handy, in this app I am using blocking sockets to listen for messages from an AMQP broker (in separate threads) and acting on them upon receipt.
Crad
@Crad: Then use select to wait on a socket, similar to the way a queue works. Do not use busy waiting or polling.
S.Lott
+5  A: 

Why sleep? You don't want to sleep, you want to wait for the threads to finish.

So

# store the threads you start in a your_threads list, then
for a_thread in your_threads:
    a_thread.join()

See: thread.join

ΤΖΩΤΖΙΟΥ
I am not expecting threads to finish, though. This is a non-ending process. Does this logic still apply?
Crad
Of course the logic still applies. You would avoid wasting even the few cycles for a "looped" sleep.
ΤΖΩΤΖΙΟΥ
This doesn't seem to work, since the threads should not terminate the process is terminated, the timeout could conceptually always come first, or am I missing something?
Crad
@Crad -- what timeout? The main thread is waiting forever for children. This is what main threads do.
S.Lott
@Crad: in my sample code I did not specify any timeout, so the join will wait forever. Do you have a reason to specify one yourself?
ΤΖΩΤΖΙΟΥ