A thread is a small execution context within a process: it carries memory and instructions, runs on a processor, and can pause when it needs a resource. While one thread is blocked on network or file input, the operating system can run another, making concurrent activity appear simultaneous even on one processor. section 8.4
Threads support concurrency through a few basic behaviors:
- The processor switches between threads after a task finishes, a timer fires, or a thread waits for a resource. section 8.4
- Multiple processor cores can increase throughput when an application divides its work into separate tasks. section 8.4
- Python manages runtime tasks with asyncio and system threads with ThreadPoolExecutor, but the Global Interpreter Lock permits only one Python thread to run at a time. section 8.5
Parallel Mandelbrot work
A Mandelbrot function can be scheduled eight times with asyncio.gather, allowing whichever task is not blocked to make progress first. Adding ThreadPoolExecutor creates execution threads, while completion order remains independent of submission order. Measurements distinguish a modest asynchronous improvement from actual parallel execution: one run fell from about 46 seconds to 42 seconds. section 8.3 section 8.4
Figure 8.4 The CPU will try to process tasks that are not blocked.
Use the CPU scheduling figure to visualize how blocked tasks allow other threads to run. section 8.4











