CPU usage of Python interpreter doing empty while loop under XP

J

Jon Perez

When you run an empty while loop under Python [with the
interpreter at its default Normal Priority], it slows
down the rest of the system. Is this normal? And should
it be something that needs to be corrected?


[Note: I'm using ActiveState Python 2.3.2 Build 232]
 
D

Dennis Lee Bieber

When you run an empty while loop under Python [with the
interpreter at its default Normal Priority], it slows
down the rest of the system. Is this normal? And should
it be something that needs to be corrected?
Normal compared to what? The same loop in C? Assembly?

An empty loop would, to my mind, indicate that there are no OS
calls being made which could allow for a task switch. This would mean
that the entire time quantum will be used for that process, before a
forced OS preemption, followed by whatever other process you are
running. If that other process performs some sort of I/O (or other
system call) the odds are your empty loop will immediately regain
control.

And since a windowing system does LOTS of I/O, there is lots of
opportunity for the empty loop to suck down CPU cycles. Stick a
sleep(0) inside it, and no doubt you will see performance return to
"normal". Even though the 0 means no actual delay is wanted, the task
swap will occur, giving the OS a chance to respond to events.

--
 
J

Jon Perez

Dennis said:
Stick a sleep(0) inside it, and no doubt you will see performance
return to "normal". Even though the 0 means no actual delay is wanted,
the task swap will occur, giving the OS a chance to respond to events.

Great, it worked.

So

while 1: sleep(0)

is a better alternative to

while 1: pass


(I'm using this for debugging purposes...)
 
P

Peter Hansen

Jon said:
Great, it worked.

So

while 1: sleep(0)

is a better alternative to

while 1: pass

(I'm using this for debugging purposes...)

How does that help your debugging? That will tell us whether
sleep(0) is a better alternative, or whether there is really
something else you should be doing instead.

(I have never had occasion to use "while 1: pass" in Python, ever.)

-Peter
 
J

Jon Perez

Peter said:
How does that help your debugging? That will tell us whether
sleep(0) is a better alternative, or whether there is really
something else you should be doing instead.

(I have never had occasion to use "while 1: pass" in Python, ever.)

-Peter

I'm trying to debug an event-driven framework I wrote myself and
there are some iffy situations where a quick and dirty way to halt
execution and view the state of some variables with print is to
insert a while 1: pass (or sleep(0)).

The only reason sleep(0) is better than pass in my situation
is that when I try to do other things under the OS before I've
had a chance to break out of the program, I don't get a slowdown.
 
P

Peter Hansen

Jon said:
I'm trying to debug an event-driven framework I wrote myself and
there are some iffy situations where a quick and dirty way to halt
execution and view the state of some variables with print is to
insert a while 1: pass (or sleep(0)).

Good, then what you are really looking for is to get away from the
print statement and learn to use "import pdb; pdb.set_trace()".

This will drop you into a convenient interpreter prompt right in
the frame where it executes (well, one level down, so just type "r"
to return from the set_trace() call to the calling level). From
this prompt you can inspect any variable in your program, execute
code by single-stepping, and so forth.

Very handy, and it completely obsoletes the "while 1: pass" idea. :)

-Peter
 
J

Jon Perez

Peter said:
Good, then what you are really looking for is to get away from the
print statement and learn to use "import pdb; pdb.set_trace()".

This will drop you into a convenient interpreter prompt right in
the frame where it executes (well, one level down, so just type "r"
to return from the set_trace() call to the calling level). From
this prompt you can inspect any variable in your program, execute
code by single-stepping, and so forth.

Very handy, and it completely obsoletes the "while 1: pass" idea. :)

-Peter

Thanks for the tip, I'll keep it in mind for next time, although
for this thing I'm doing, I might not be able to use pdb because
the event driven framework I'm doing (built on top of Fredrik
Lundh's console) has to do with a text user interface and I can't
have things messing up the screen which is what would happen if I
used the pdb technique.

To illustrate how careful I have to be about preserving what's on
the screen, I have a debugmsg() function which saves the current
cursor position, prints out variable values (or whatever I like)
to a small unused corner of the screen, then restores the cursor
position. Because it's an event driven framework, program flow
is hard to predict, so there are situations where I need the
program to effectively 'hang' at certain portions (a kind of breakpoint
if you will) so I can see the debug message as well as the current
state of the screen without it being overwritten immediately by
either pdb output or succeeding code that does a screen clear or
refresh.

I would be able to use pdb if Console allowed you to separate
the screen buffer for the program output with that of the command
line from which you invoked said program (where the error messages
and pdb output should go to), but there doesn't seem to be a way
to do that.
 
P

Peter Hansen

Jon said:
I would be able to use pdb if Console allowed you to separate
the screen buffer for the program output with that of the command
line from which you invoked said program (where the error messages
and pdb output should go to), but there doesn't seem to be a way
to do that.

There are a variety of ways to get remote debugging and
remote interpreter prompts, some supported by the standard
library modules (such as the cmd module). I also note
in the pdb module documentation that the Pdb class itself
is explicitly extensible, suggesting you could rather
easily extend it to support external interfaces other than
the local console. And a quick Google search suggests that
the functionality you needed was added (probably using the
time machine again) around last August:

http://mail.python.org/pipermail/patches/2003-August/013227.html

(Probably your current approach will suffice for now, but
consider this for the next time, as it will give you
significantly enhanced debugging abilities, including the
possibly useful ability to launch a debugger prompt
as soon as an exception is raised, right where the exception
is caught.)

-Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top