[4] => 4
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[3] => 4
[2] => 3
[1] => 2
[2] => 4
[0] => 1
[1] => 3
[1] => 4
[0] => 2
[0] => 3
[0] => 4
Main thread exiting.
Of course, threads are for much more than counting. We’ll put shared global data to
more practical use in “Adding a User Interface” on page 867, where it will serve as
completion signals from child processing threads transferring data over a network to a
main thread controlling a tkinter GUI display, and again later in Chapter 10’s thread-
tools and Chapter 14’s PyMailGUI to post results of email operations to a GUI (watch
for “Preview: GUIs and Threads” on page 208 for more pointers on this topic). Global
data shared among threads also turns out to be the basis of queues, which are discussed
later in this chapter; each thread gets or puts data using the same shared queue object.
The threading Module
The Python standard library comes with two thread modules: _thread, the basic lower-
level interface illustrated thus far, and threading, a higher-level interface based on
objects and classes. The threading module internally uses the _thread module to im-
plement objects that represent threads and common synchronization tools. It is loosely
based on a subset of the Java language’s threading model, but it differs in ways that
only Java programmers would notice.‖ Example 5-11 morphs our counting threads
example again to demonstrate this new module’s interfaces.
Example 5-11. PP4E\System\Threads\thread-classes.py
"""
thread class instances with state and run() for thread's action;
uses higher-level Java-like threading module object join method (not
mutexes or shared global vars) to know when threads are done in main
parent thread; see library manual for more details on threading;
"""
import threading
‖But in case this means you, Python’s lock and condition variables are distinct objects, not something inherent
in all objects, and Python’s Thread class doesn’t have all the features of Java’s. See Python’s library manual
for further details.
Threads | 199