Crash in thread on program termination

Peter Hansen peter at engcorp.com
Wed Feb 9 18:02:09 EST 2005


Alec Wysoker wrote:
> I have several programs that have two or more threads.  The threads 
 > that are not the main thread are daemon threads, i.e. the fact
 > that they are running should not stop the program from terminating
 > if the main thread (the only non-daemon thread) terminates.
> 
> Traceback (most recent call last):
[...]
>   File "C:\Python23\lib\threading.py", line 238, in notify
>     currentThread() # for side-effect
> TypeError: 'NoneType' object is not callable
> 
> What seems to be happening is that at the time the thread is stopped, the threading 
 > module object is no longer in an unhealthy state.
> I.e. threading.currentThread is None.

In a nutshell, the interpreter is dismantling itself while the
daemon threads merrily continue to run -- or attempt to.  During
one of the steps in this dismantling process, the interpreter
goes through and rebinds all the globals in all modules to the
None object.  You're seeing the effect of a daemon thread
encountering the inevitable bad effects of this.

For background, search the list archives and focus on messages
written by Tim Peters.  Also try Googling the web for, say,
"python interpreter daemon thread shutdown nonetype" or
something... there are various not entirely conclusive threads
on the subject here and there.

I'm not sure there is a generally acceptable solution.  You'll
notice that the ultimate response of the code in __bootstrap()
is still to try to print to stderr... which is a harmless but
otherwise perhaps distracting thing to do.

In my own code where this was a bother, I have something like
the following at the highest levels of the run() method of
my daemon threads:

     def run(self):
         try:
             # do real stuff here
         except Exception, ex:
             if (self.isDaemon() and
                 isinstance(ex, AttributeError) and
                 ex[0].startswith("'NoneType'")):
                 pass

In other words, I'm attempting to catch those specific types of
spurious error and avoid letting __bootstrap() have its say.
At the moment, 98% of the spurious messages are gone and that's
good enough for my purposes...

-Peter



More information about the Python-list mailing list