if not self._initialized:
raise RuntimeError("Thread.__init__() not called")
if not self._started.is_set():
raise RuntimeError("cannot join thread before it is started")
if self is current_thread():
raise RuntimeError("cannot join current thread")
self._wait_for_tstate_lock()
# the behavior of a negative timeout isn't documented, but
# historically .join(timeout=x) for x<0 has acted as if timeout=0
self._wait_for_tstate_lock(timeout=max(timeout, 0))
def _wait_for_tstate_lock(self, block=True, timeout=-1):
# Issue #18808: wait for the thread state to be gone.
# At the end of the thread's life, after all knowledge of the thread
# is removed from C data structures, C code releases our _tstate_lock.
# This method passes its arguments to _tstate_lock.acquire().
# If the lock is acquired, the C code is done, and self._stop() is
# called. That sets ._is_stopped to True, and ._tstate_lock to None.
if lock is None: # already determined that the C code is done
elif lock.acquire(block, timeout):
"""A string used for identification purposes only.
It has no semantics. Multiple threads may be given the same name. The
initial name is set by the constructor.
assert self._initialized, "Thread.__init__() not called"
assert self._initialized, "Thread.__init__() not called"
"""Thread identifier of this thread or None if it has not been started.
This is a nonzero integer. See the get_ident() function. Thread
identifiers may be recycled when a thread exits and another thread is
created. The identifier is available even after the thread has exited.
assert self._initialized, "Thread.__init__() not called"
if _HAVE_THREAD_NATIVE_ID:
"""Native integral thread ID of this thread, or None if it has not been started.
This is a non-negative integer. See the get_native_id() function.
This represents the Thread ID as reported by the kernel.
assert self._initialized, "Thread.__init__() not called"
"""Return whether the thread is alive.
This method returns True just before the run() method starts until just
after the run() method terminates. The module function enumerate()
returns a list of all alive threads.
assert self._initialized, "Thread.__init__() not called"
if self._is_stopped or not self._started.is_set():
self._wait_for_tstate_lock(False)
return not self._is_stopped
"""Return whether the thread is alive.
This method is deprecated, use is_alive() instead.
warnings.warn('isAlive() is deprecated, use is_alive() instead',
DeprecationWarning, stacklevel=2)
"""A boolean value indicating whether this thread is a daemon thread.
This must be set before start() is called, otherwise RuntimeError is
raised. Its initial value is inherited from the creating thread; the
main thread is not a daemon thread and therefore all threads created in
the main thread default to daemon = False.
The entire Python program exits when only daemon threads are left.
assert self._initialized, "Thread.__init__() not called"
def daemon(self, daemonic):
if not self._initialized:
raise RuntimeError("Thread.__init__() not called")
if self._started.is_set():
raise RuntimeError("cannot set daemon status of active thread")
self._daemonic = daemonic
def setDaemon(self, daemonic):
from _thread import (_excepthook as excepthook,
_ExceptHookArgs as ExceptHookArgs)
# Simple Python implementation if _thread._excepthook() is not available
from traceback import print_exception as _print_exception
from collections import namedtuple
_ExceptHookArgs = namedtuple(
'exc_type exc_value exc_traceback thread')
def ExceptHookArgs(args):
return _ExceptHookArgs(*args)
Handle uncaught Thread.run() exception.
if args.exc_type == SystemExit:
# silently ignore SystemExit
if _sys is not None and _sys.stderr is not None:
elif args.thread is not None:
stderr = args.thread._stderr
# do nothing if sys.stderr is None and sys.stderr was None
# when the thread was created
# do nothing if sys.stderr is None and args.thread is None
if args.thread is not None:
print(f"Exception in thread {name}:",
_print_exception(args.exc_type, args.exc_value, args.exc_traceback,
def _make_invoke_excepthook():
# Create a local namespace to ensure that variables remain alive
# when _invoke_excepthook() is called, even if it is called late during
# Python shutdown. It is mostly needed for daemon threads.
old_excepthook = excepthook
old_sys_excepthook = _sys.excepthook
if old_excepthook is None:
raise RuntimeError("threading.excepthook is None")
if old_sys_excepthook is None:
raise RuntimeError("sys.excepthook is None")
sys_exc_info = _sys.exc_info
def invoke_excepthook(thread):
args = ExceptHookArgs([*sys_exc_info(), thread])
exc.__suppress_context__ = True
if local_sys is not None and local_sys.stderr is not None:
stderr = local_sys.stderr
local_print("Exception in threading.excepthook:",
if local_sys is not None and local_sys.excepthook is not None:
sys_excepthook = local_sys.excepthook
sys_excepthook = old_sys_excepthook
sys_excepthook(*sys_exc_info())
# Break reference cycle (exception stored in a variable)
# The timer class was contributed by Itamar Shtull-Trauring
"""Call a function after a specified number of seconds:
t = Timer(30.0, f, args=None, kwargs=None)
t.cancel() # stop the timer's action if it's still waiting
def __init__(self, interval, function, args=None, kwargs=None):
self.args = args if args is not None else []
self.kwargs = kwargs if kwargs is not None else {}
"""Stop the timer if it hasn't finished yet."""
self.finished.wait(self.interval)
if not self.finished.is_set():
self.function(*self.args, **self.kwargs)
# Special thread class to represent the main thread
class _MainThread(Thread):
Thread.__init__(self, name="MainThread", daemon=False)
if _HAVE_THREAD_NATIVE_ID:
_active[self._ident] = self
# Dummy thread class to represent threads not started here.
# These aren't garbage collected when they die, nor can they be waited for.
# If they invoke anything in threading.py that calls current_thread(), they
# leave an entry in the _active dict forever after.
# Their purpose is to return *something* from current_thread().
# They are marked as daemon threads so we won't wait for them
# when we exit (conform previous semantics).
class _DummyThread(Thread):
Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True)
if _HAVE_THREAD_NATIVE_ID:
_active[self._ident] = self
assert not self._is_stopped and self._started.is_set()
def join(self, timeout=None):
assert False, "cannot join a dummy thread"
"""Return the current Thread object, corresponding to the caller's thread of control.
If the caller's thread of control was not created through the threading
module, a dummy thread object with limited functionality is returned.
return _active[get_ident()]
currentThread = current_thread
"""Return the number of Thread objects currently alive.
The returned count is equal to the length of the list returned by
return len(_active) + len(_limbo)
activeCount = active_count
# Same as enumerate(), but without the lock. Internal use only.
return list(_active.values()) + list(_limbo.values())
"""Return a list of all Thread objects currently alive.
The list includes daemonic threads, dummy thread objects created by
current_thread(), and the main thread. It excludes terminated threads and
threads that have not yet been started.
return list(_active.values()) + list(_limbo.values())
from _thread import stack_size
# Create the main thread object,
# and make it available for the interpreter
# (Py_Main) as threading._shutdown.
_main_thread = _MainThread()
Wait until the Python thread state of all non-daemon threads get deleted.
# Obscure: other threads may be waiting to join _main_thread. That's
# dubious, but some code does it. We can't wait for C code to release
# the main thread's tstate_lock - that won't happen until the interpreter
# is nearly dead. So we release it here. Note that just calling _stop()
# isn't enough: other threads may already be waiting on _tstate_lock.
if _main_thread._is_stopped:
# _shutdown() was already called
tlock = _main_thread._tstate_lock
# The main thread isn't finished yet, so its thread state lock can't have
# Join all non-deamon threads
with _shutdown_locks_lock:
locks = list(_shutdown_locks)
# new threads can be spawned while we were waiting for the other
"""Return the main thread object.
In normal conditions, the main thread is the thread from which the
Python interpreter was started.
# get thread-local implementation, either from the thread
# module, or from the python fallback
from _thread import _local as local
from _threading_local import local
Cleanup threading module state that should not exist after a fork.
# Reset _active_limbo_lock, in case we forked while the lock was held
# by another (non-forked) thread. http://bugs.python.org/issue874900
global _active_limbo_lock, _main_thread
global _shutdown_locks_lock, _shutdown_locks
_active_limbo_lock = _allocate_lock()
# fork() only copied the current thread; clear references to others.
current = _active[get_ident()]
# fork() was called in a thread which was not spawned
# by threading.Thread. For example, a thread spawned
# by thread.start_new_thread().
# reset _shutdown() locks: threads re-register their _tstate_lock below
_shutdown_locks_lock = _allocate_lock()
# Dangling thread instances must still have their locks reset,
# because someone may join() them.
threads = set(_enumerate())
threads.update(_dangling)
# Any lock/condition variable may be currently locked or in an
# invalid state, so we reinitialize them.
# There is only one active thread. We reset the ident to
# its new value since it can have changed.
thread._reset_internal_locks(True)
new_active[ident] = thread
# All the others are already stopped.
thread._reset_internal_locks(False)
_active.update(new_active)
if hasattr(_os, "register_at_fork"):
_os.register_at_fork(after_in_child=_after_fork)