Functional Python Programming

(Wang) #1

The Multiprocessing and


Threading Modules


When we eliminate complex, shared state and design around non-strict processing,
we can leverage parallelism to improve performance. In this chapter, we'll look at
the multiprocessing and multithreading techniques that are available to us. Python
library packages become particularly helpful when applied to algorithms that permit
lazy evaluation.


The central idea here is to distribute a functional program across several threads
within a process or across several processes. If we've created a sensible functional
design, we don't have complex interactions among application components; we have
functions that accept argument values and produce results. This is an ideal structure
for a process or a thread.


We'll focus on the multiprocessing and concurrent.futures modules.
These modules allow a number of parallel execution techniques.


We'll also focus on process-level parallelism instead of multithreading. The idea
behind process parallelism allows us to ignore Python's Global Interpreter Lock
(GIL) and achieve outstanding performance.


For more information on Python's GIL, see https://docs.python.org/3.3/c-api/
init.html#thread-state-and-the-global-interpreter-lock.


We won't emphasize features of the threading module. This is often used for
parallel processing. If we have done our functional programming design well, any
issues that stem from multithreaded write access should be minimized. However, the
presence of the GIL means that multithreaded applications in CPython suffer from
some small limitations. As waiting for I/O doesn't involve the GIL, it's possible that
some I/O bound programs might have unusually good performance.

Free download pdf