[Python-Dev] Killing threads

Jeff Epler jepler@mail.inetnebr.com
Mon, 28 May 2001 21:32:05 -0500


On Mon, May 28, 2001 at 09:49:29PM -0400, Tim Peters wrote:
> Here's a recent bug report on a Red Hot box that may be related:
> 
> http://sf.net/tracker/?group_id=5470&atid=105470&func=detail&aid=426735
> 
> I have no idea what's supposed to happen if you call os._exit from a
> *spawned* thread (perhaps that's what you did too?  I did not) -- threads
> are outside the scope of the C std, so I suppose it's a x-platform
> crapshoot.

I wrote that program after the first go-round about _exit and threads,
and when I got behavior I didn't expect, I entered it in the SF bug
tracker.

My reasoning: The documentation for _exit() says it is "used to exit the
child process after a fork()", and my model for thinking about threads
is that they're "child processes, but ...".  Thus, invoking os._exit()
in a thread made sense to me, meaning "ask the OS to destroy this thread
now, but leave my file descriptors, etc., alone for the other threads."

Your suggestion in the tracker of writing the equivalent C program is a
good one, though my suspicion (which I did not voice in the SF report)
was that perhaps the thread which called _exit() held the GIL, in which
case it was in some sense Python's fault that execution didn't continue.
In any case, I don't have the faintest idea how to program threads in
C/pthreads, so I can't write the "equivalent C program".

In fact, a traceback from the hung "sleep(1)" thread shows

(gdb) where
#0  0x4008c656 in __sigsuspend (set=0xbffff5b0) at ../sysdeps/unix/sysv/linux/sigsuspend.c:45
#1  0x4002ee39 in __pthread_wait_for_restart_signal (self=0x400387c0) at pthread.c:934
#2  0x4002b05c in pthread_cond_wait (cond=0x80cf5cc, mutex=0x80cf5d8) at restart.h:34
#3  0x08067ba0 in PyThread_acquire_lock () at eval.c:41
#4  0x08051ff1 in PyEval_RestoreThread () at eval.c:41
#5  0x40019ef9 in floatsleep () at eval.c:41
#6  0x400193fd in time_sleep () at eval.c:41
[...]

While those line numbers look a little fishy (eval.c:41 for all three
frames?), I think this might support my supposition.

Of course, if os._exit() has no intended use in a threaded program, then
this behavior is as good as any.  <wink>

Jeff