[3] => 0
[1] => 1
[3] => 1
[3] => 1
[0] => 1[2] => 1
[3] => 1
[0] => 1[2] => 1
[4] => 1
[1] => 2
[3] => 2[4] => 2
[3] => 2[4] => 2
[0] => 2
[3] => 2[4] => 2
[0] => 2
[2] => 2
[3] => 2[4] => 2
[0] => 2
[2] => 2
...more output omitted...
Main thread exiting.
If this looks odd, it’s because it should. In fact, this demonstrates probably the most
unusual aspect of threads. What’s happening here is that the output of the 5 threads
run in parallel is intermixed—because all the threaded function calls run in the same
process, they all share the same standard output stream (in Python terms, there is just
one sys.stdout file between them, which is where printed text is sent). The net effect
is that their output can be combined and confused arbitrarily. In fact, this script’s
output can differ on each run. This jumbling of output grew even more pronounced in
Python 3, presumably due to its new file output implementation.
More fundamentally, when multiple threads can access a shared resource like this, their
access must be synchronized to avoid overlap in time—as explained in the next section.
Synchronizing access to shared objects and names
One of the nice things about threads is that they automatically come with a cross-task
communications mechanism: objects and namespaces in a process that span the life of
threads are shared by all spawned threads. For instance, because every thread runs in
the same process, if one Python thread changes a global scope variable, the change can
be seen by every other thread in the process, main or child. Similarly, threads can share
and change mutable objects in the process’s memory as long as they hold a reference
to them (e.g., passed-in arguments). This serves as a simple way for a program’s threads
to pass information—exit flags, result objects, event indicators, and so on—back and
forth to each other.
The downside to this scheme is that our threads must sometimes be careful to avoid
changing global objects and names at the same time. If two threads may change a shared
object at once, it’s not impossible that one of the two changes will be lost (or worse,
Threads | 193