Also known as: futures
The concurrent.futures module provides a high-level interface for running tasks in parallel using thread or process pools. Its two main classes — ThreadPoolExecutor (for I/O-bound tasks) and ProcessPoolExecutor (for CPU-bound tasks) — share the same API, making it easy to switch between threading and multiprocessing.
Both executors are used as context managers and provide a submit(fn, *args) method that returns a Future object. The Future represents the eventual result of the computation: you call .result() to block until the value is available, or .done() to check without blocking. The module also provides as_completed(futures) (yield futures as they finish) and executor.map(fn, iterable) (a parallel version of map()).
concurrent.futures is the recommended starting point for parallelism in Python because it handles the complexities of thread and process management. It integrates with asyncio via loop.run_in_executor(), which runs a synchronous function in a thread or process pool without blocking the event loop. For most parallel workloads, concurrent.futures strikes the right balance between simplicity and control.
Discussed in:
- Chapter 19: Concurrency and Parallelism — concurrent.futures: The Unified Interface