To better set us up to understand how concurrency works in the Python world, we’ll first need to understand the basics about how threads and processes work. We’ll then examine how to use them for multithreading and multiprocessing to do work concurrently. Let’s start with some definitions around processes and threads.
PROCESS:
THREAD:
Multithreaded applications are a common way to achieve concurrency in many programming languages. There are a few challenges in utilizing concurrency with threads in Python, however. Multithreading is only useful for I/O-bound work because we are limited by the global interpreter lock. Multithreading is not the only way we can achieve concurrency; we can also create multiple processes to do work concurrently for us. This is known as multiprocessing. In multiprocessing, a parent process creates one or more child processes that it manages. It can then distribute work to the child processes. Python gives us the multiprocessing module to handle this. The API is similar to that of the threading module. We first create a process with a target function. Then, we call its start method to execute it and finally its join method to wait for it to complete running.