[ python-Bugs-1596321 ] KeyError at exit after 'import threading' in other thread

SourceForge.net noreply at sourceforge.net
Wed Nov 15 08:02:23 CET 2006


Bugs item #1596321, was opened at 2006-11-14 15:02
Message generated for change (Comment added) made by cwalther
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1596321&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Threads
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Christian Walther (cwalther)
Assigned to: Nobody/Anonymous (nobody)
Summary: KeyError at exit after 'import threading' in other thread

Initial Comment:
Python 2.4.3 on Windows 2000, though the code in
question seems unchanged in current SVN (r46919).

I'm using Python embedded in a multithreaded C++
application. When 'import threading' is first done in
some Python script that runs in thread A, I get the
following exception when a different thread B calls
Py_Finalize():

Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Python24\lib\atexit.py", line 24, in
_run_exitfuncs
    func(*targs, **kargs)
  File "C:\Python24\lib\threading.py", line 636, in
__exitfunc
    self._Thread__delete()
  File "C:\Python24\lib\threading.py", line 522, in
__delete
    del _active[_get_ident()]
KeyError: 680
Error in sys.exitfunc:
Traceback (most recent call last):
  File "C:\Python24\lib\atexit.py", line 24, in
_run_exitfuncs
    func(*targs, **kargs)
  File "C:\Python24\lib\threading.py", line 636, in
__exitfunc
    self._Thread__delete()
  File "C:\Python24\lib\threading.py", line 522, in
__delete
    del _active[_get_ident()]
KeyError: 680

The reason seems to be that the threading module uses
the thread ID of the calling thread as a key to store
its _MainThread instance on initialization, and again
the thread ID of the calling thread to delete it in its
exit function. If these two threads are not the same,
the described KeyError occurs.

I didn't study this in all detail, but it seems to me
that threading.Thread.__delete() does the wrong thing.
By doing 'del _active[_get_ident()]', it removes the
instance for the calling thread from the _active
dictionary. What it should be doing is removing *self*
from that dictionary. Is that correct?

----------------------------------------------------------------------

>Comment By: Christian Walther (cwalther)
Date: 2006-11-15 08:02

Message:
Logged In: YES 
user_id=1061789
Originator: YES

I'm not calling Py_Finalize from a non-main thread. What I called "thread
B" is the main thread. It's the script that first imports the threading
module that runs in a non-main thread (and running user-defined scripts in
non-main threads is hopefully not unsafe, or there wouldn't be much point
in supporting multithreading at all in Python).

It didn't even occur to me that this could be reproduced in pure Python
code, so I didn't include an example in my original post. Of course, it
can - see attachment. Tested on Python 2.3.5 on Mac OS X.

----------------------------------------------------------------------

Comment By: Brett Cannon (bcannon)
Date: 2006-11-14 22:59

Message:
Logged In: YES 
user_id=357491
Originator: NO

Well, I don't think you should be calling Py_Finalize() from the non-main
thread.  That just seems unsafe to me.

Regardless, though, could you write up some quick Python code that
triggers this?

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1596321&group_id=5470


More information about the Python-bugs-list mailing list