import _thread as thread
exitstat = 0
def child():
global exitstat # process global names
exitstat += 1 # shared by all threads
threadid = thread.get_ident()
print('Hello from child', threadid, exitstat)
thread.exit()
print('never reached')
def parent():
while True:
thread.start_new_thread(child, ())
if input() == 'q': break
if name == 'main': parent()
The following shows this script in action on Windows; unlike forks, threads run in the
standard version of Python on Windows, too. Thread identifiers created by Python
differ each time—they are arbitrary but unique among all currently active threads and
so may be used as dictionary keys to keep per-thread information (a thread’s id may be
reused after it exits on some platforms):
C:\...\PP4E\System\Exits> python testexit_thread.py
Hello from child 4908 1
Hello from child 4860 2
Hello from child 2752 3
Hello from child 8964 4
q
Notice how the value of this script’s global exitstat is changed by each thread, because
threads share global memory within the process. In fact, this is often how threads com-
municate in general. Rather than exit status codes, threads assign module-level globals
or change shared mutable objects in-place to signal conditions, and they use thread
module locks and queues to synchronize access to shared items if needed. This script
might need to synchronize, too, if it ever does something more realistic—for global
counter changes, but even print and input may have to be synchronized if they overlap
stream access badly on some platforms. For this simple demo, we forego locks by as-
suming threads won’t mix their operations oddly.
As we’ve learned, a thread normally exits silently when the function it runs returns,
and the function return value is ignored. Optionally, the _thread.exit function can be
called to terminate the calling thread explicitly and silently. This call works almost
exactly like sys.exit (but takes no return status argument), and it works by raising a
SystemExit exception in the calling thread. Because of that, a thread can also prema-
turely end by calling sys.exit or by directly raising SystemExit. Be sure not to call
os._exit within a thread function, though—doing so can have odd results (the last time
Program Exits | 221