Jeffrey Kintscher <websur...@surf2c.net> added the comment:

It looks like the problem is that Thread._tstate_lock doesn't get released 
until Thread.join() is called. _tstate_lock is of type LockType, which has 
different definitions when using the threading module or the dummy_threading 
module. It is defined in Modules/_threadmodule.c when using the threading 
module, and in Lib/_dummy_thread.py when using the dummy_threading module.

The lock is acquired when the new thread starts and is supposed to be released 
when the thread exits. Thread.is_alive() and Thread.join() both call 
Thread._wait_for_tstate_lock(), which in turn calls 
Thread._tstate_lock.acquire(). When Thread._wait_for_tstate_lock() successfully 
acquires the lock, it calls Thread._stop() to set the Thread._is_stop flag to 
indicate that the thread has exited. The Thread._is_stop flag is checked by 
Thread.is_alive() before trying to acquire the lock.

Thread.is_alive() passes False to Thread._wait_for_tstate_lock(), while 
Thread.join() effectively passes True as the default parameter. 
Thread._wait_for_tstate_lock() then passes the parameter value to 
Thread._tstate_lock.acquire() to indicate whether to block until the lock is 
acquired (True) or try to acquire the lock and return immediately (False).

The return value of the LockType.acquire() function indicates whether (True) or 
not (False) the lock was acquired. The function defined in the dummy_threading 
module always returns True when passed True and False when passed False. Since 
Thread.is_alive() passes False to Thread._wait_for_tstate_lock() and onwards to 
Thread._tstate_lock.acquire(), Thread._tstate_lock.acquire() returns False 
which causes Thread._wait_for_tstate_lock() to skip calling Thread._stop() and 
the Thread._is_stop flag doesn't get set. Thread.is_alive() returns "not 
self._is_stop", so it always returns True.

Thread.join() passes True, so Thread._tstate_lock.acquire() returns True and 
Thread._wait_for_tstate_lock() calls Thread._stop to set the Thread._is_stop 
flag. Subsequent calls to Thread.is_alive() see that Thread._is_stop flag is 
set and return False (i.e. "not self._is_stop") without checking the lock.

In a nutshell, the way the code is written, Thread.is_alive() always returns 
True until after Thread.join() is called.

----------
versions: +Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue33777>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to