time.sleep() and cpu cycles

Tim Peters tim.one at home.com
Fri Feb 9 14:19:34 EST 2001


[Timothy Grant]
> ... Linux ... (kernel 2.2.14).
>
> ... python logging script that reads the inode info out of /proc
> every 10 seconds, and then uses python's logging facilities

What are those?  "print"?

> to write out a log file with what it found.
> ...
> When the box is under load with users logged running things, the
> python process does not interfere with anything.
> ...
> However, on an unloaded system, the python process is taking 60%
> of the CPU.  Maybe that's the way it should be, but it sure seemed
> odd to me.

Me too.

> I use time.sleep() for my delay loop, and was wondering if there
> is a better way to put a task to sleep,

No.

> or if what I'm seeing is normal behaviour.

Certainly not normal behavior under Windows <wink>.  But unlike most of
Python's platform-dependent functions, time.sleep() isn't just a thin
wrapper around the C library function of the same name.  It eventually calls
Modules/timemodule.c's floatsleep(), which strives to shut the task up with
the finest-grain precision it can get on each platform, by hook or by crook.

In the Linux case, I expect it uses the first #ifdef'ed block:

#if defined(HAVE_SELECT) && !defined(__BEOS__)
	struct timeval t;
	double frac;
	frac = fmod(secs, 1.0);
	secs = floor(secs);
	t.tv_sec = (long)secs;
	t.tv_usec = (long)(frac*1000000.0);
	Py_BEGIN_ALLOW_THREADS
	if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
#ifdef EINTR
		if (errno != EINTR) {
#else
		if (1) {
#endif
			Py_BLOCK_THREADS
			PyErr_SetFromErrno(PyExc_IOError);
			return -1;
		}
	}
	Py_END_ALLOW_THREADS

So one thing to check is whether a tiny C program employing this same abuse
of select() also chews up absurd amounts of CPU time.  In that case, it's
select()'s fault; else the CPU utilization is somewhere you haven't yet
suspected.





More information about the Python-list mailing list