Staying Safe When Writing Concurrent Code

Intuitive Python — by David Muller (27 / 41)

The Pragmatic Programmers
The Pragmatic Programmers

--

👈 Choosing ThreadPoolExecutor or ProcessPoolExe cutor | TOC | Building with an Alternate Model: asyncio 👉

In general, it is best to share as little as possible between different threads and processes. Problems tend to start as soon as you try to share objects between different thread or process objects.

Python does include a set of tools for locking and otherwise passing and sharing state when using Thread or Process objects including threading.Lock, threading.Barrier, threading.Semaphore, multiprocessing.Queue, and several others. The aforementioned tools are powerful and can be used to write elegant concurrent programs.

When writing the concurrent code, however, I find it helpful to follow a simple heuristic: share nothing. Even though Python provides powerful tools for writing concurrent programs, they are not the first thing I reach for — instead of using a tool like threading.Lock to coordinate threads, is it possible to create two threads that work without coordinating amongst themselves at all?

At its core, “share nothing” means avoiding writing code that looks similar to this:

share_nothing_wrong.py

​ ​def​ ​add_elements​(a_list):
​ a_list += [​"a"​, ​"b"​, ​"c"​]
​ ​return​ a_list
​ ​if​ __name__ == ​"__main__"​:
​ ​with​ ThreadPoolExecutor() ​as​ executor:
​…

--

--

The Pragmatic Programmers
The Pragmatic Programmers

We create timely, practical books and learning resources on classic and cutting-edge topics to help you practice your craft and accelerate your career.