Python Concurrency Learning Paths
Python concurrency is a big topic and can be challenging for beginners.
This page provides you with step-by-step learning paths that you can use to get started and get good at Python concurrency.
You might want to bookmark this page and come back to it again and again.
New to Concurrency in Python
The first step is to get familiar with the basics of concurrency in Python.
- Step 1: Get familiar with the Python concurrency landscape
- Step 2: Get familiar with the Python concurrency APIs that are available
- Step 3: Get familiar with the API docs, books, and glossary of terms.
You can then dive into one of the specific concurrency APIs below.
Threading Learning Path
Python provides thread-based concurrency in the “threading” module.
This section provides a learning path that you can use to get started and get effective with the threading module, super fast.
- Step 1: Discover what a thread is in Python.
- Step 2: Discover how to run code in a new thread.
- Step 3: Discover how to get the most out of threads.
Next, you can browse all tutorials or dive into a topic below to learn more.
Configure Threads
- How to Configure Threads
- How to Change the Thread Name
- How to Use Daemon Threads
- Handle Unexpected Exceptions
Basic Threading
- Thread Blocking Call
- What is the Main Thread
- How to Query Thread Attributes
- Thread Utility Functions
- How to Use Thread-Local Data
- How to Join a Thread
- How to Restart a Thread
- Wait for a Result from a Thread
Intermediate
- Share Variables Between Threads
- Threading Return Values
- How to Stop a Thread
- How to Close a Thread
- How to Kill a Thread
- Auto-Start Threads
- How to Sleep a Thread
Advanced Threading
- 5 Threading Anti-Patterns
- Interrupt the Main Thread
- Thread Context Variables
- Thread Stack Size
- Context Switch Interval
Thread-Safe Queues
- Thread-Safe Queue
- Thread-Safe SimpleQueue
- Thread-Safe LifoQueue
- Thread-Safe Priority Queue
- Queue task_done() and join()
Background Threads
Thread Safety
- Thread Atomic Operations
- Volatile Variables
- Thread-Safe Counter
- Thread-Safe Print
- Thread-Safe Logging
- Thread-Safe Dictionary
- Thread-Safe List
- Thread-Safe Write to File
- Thread-Safety Context Managers
- Thread-Safe Random Numbers
Failure Modes
- How to Identify a Deadlock
- Thread Livelocks in Python
- Race Condition With Timing
- Race Condition Shared Variable
- Thread Starvation in Python
- Why hate the GIL
Sync Primitives
- Threading Mutex Lock
- Threading RLock
- Threading Condition Variable
- Threading Semaphore
- Threading Event Object
- Threading Timer Thread
- Threading Barrier
- Lock vs Semaphore
- Advanced Semaphore Examples
Intermediate Locking
Advanced Locking
- Lock Contention
- Lock Striping in Python
- Lock Splitting in Python
- Lock Retry with Back-Off
- Thread Lock Overhead
- How to Use a Spinlock
- How to Use Busy Waiting
Thread Patterns
Multiprocessing Learning Path
Python provides process-based concurrency in the “multiprocessing” module.
This section provides a learning path that you can use to get started and get effective with the multiprocessing module, super fast.
- Step 1: Discover what a process is in Python.
- Step 2: Discover how to run code in a new child process.
- Step 3: Discover how to get the most out of processes.
Next, you can browse all tutorials or dive into a topic below to learn more.
Configure Processes
- Change the Process Name
- Daemon Process in Python
- Multiprocessing Start Methods
- Configure Child Process
Basic Processes
- Main Process in Python
- Main Thread of Process
- Get Process By Name
- How to Get the Process PID
- Get the Number of CPUs
- Process Utility Functions
- How to Query Process Status
- How to Restart a Process
- How to Join a Process
- Child stop main process
- print() from a Child Process
Intermediate
- Multiprocessing for-loops
- Nested for-loops
- Why Not Always Use Processes
- Multiprocessing Best Practices
- Multiprocessing Logging
- Threads in Processes
- Automatically Start Processes
- Return Value From Process
- Return Value Without Change
Advanced Processes
- Multiprocessing Context
- Multiprocessing Freeze Support
- Multiprocessing vs GIL
- Multiprocessing vs Threading
- Inherit Global Variables
- Shared ctypes in Python
- Use 100% of CPUs
- Order parallel tasks
- Execute task with a delay
- Execute task with timeout
Failure Modes
Parents and Children
Sync Primitives
- Process-Safe in Python
- Multiprocessing Lock
- Multiprocessing RLock
- Multiprocessing Event Object
- Multiprocessing Semaphore
- Multiprocessing Condition Var
- Multiprocessing Barrier
- Process-Safe Counter
Queues and Pipes
- Multiprocessing Queue
- Multiprocessing SimpleQueue
- Multiprocessing JoinableQueue
- Multiprocessing Pipe
Killing Processes
- How to Safely Stop a Process
- Kill a Process in Python
- Kill Process By PID
- Kill All Child Processes
- Orphaned Processes
- Exit a Process with sys.exit()
- Process Exit Codes
- Stop main process leave child
Managers
- What is a manager
- Manager example
- Manager with custom class
- Manager with primitives
- Manager share object
- Manager share queue
- Manager server process
- Manager shared namespace
- Manager nested proxies
Comparison
- Forking is faster than spawning
- Processes slower than threads
- Threads faster at sharing data
- Inheriting is faster than sharing
Shared Memory
Asyncio Learning Path
Python provides coroutine-based concurrency in the “asyncio” module.
This section provides a learning path that you can use to get started and get effective with the asyncio module, super fast.
- Step 1: Discover asyncio programs in Python.
- Step 2: Discover how to create and run tasks in asyncio.
- Step 3: Discover how to get the most out of asyncio.
- Asyncio in Python: The Complete Guide
- All Books on Asyncio
- Python Asyncio Jump-Start (my beginner book)
- Python Asyncio Mastery (my intermediate book)
Next, you can browse all tutorials or dive into a topic below to learn more.
Asyncio Language
- What is async/await
- How to use “async def”
- How to use “async for”
- How to use “async with”
- How to use “await”
- Asyncio dunder methods
- Python asyncio keywords
- What are awaitables
- Why hate asyncio
Async Tasks
- What is a Task
- How to create a task
- How to check task status
- How to get task results
- How to cancel a task
- How to handle task exceptions
- How to use task names
- How to use done callbacks
- How to get coroutine from a task
- How to get the current task
- How to get all tasks
- What is a “pending” task
- What is asyncio main task
Iterators and Generators
Async Primitives
- Coroutine safety
- Async mutex locks
- Async events
- Async condition variables
- Async semaphores
- Async bounded semaphores
- Using thread locks in asyncio
- Coroutine race conditions
- Coroutine deadlocks
Advanced Operations
- Run follow-up tasks
- Show progress of tasks
- Wait for all background tasks
- Cancel All Tasks if One Fails
- Async for loop
- Run coroutine outside asyncio
Async Streams
Asyncio Development
- Profile Asyncio Programs
- Profile Async With line_profiler
- How to debug asyncio
- Find stuck asyncio tasks
- Asyncio static analysis
Common Faults
- Coroutine never awaited
- Future and Future Incompatible
- Future vs Future
- Disappearing task bug
- RuntimeWarning: tracemalloc
- Exception never retrieved
Asyncio Logging
Basics
- What is asyncio
- Why use asyncio
- What is the event loop
- Asyncio vs threading
- Asyncio common errors
- Coroutines faster than threads
- Coroutines vs threads
- Coroutines use less memory
- Two asyncio APIs
- When do tasks context switch
Coroutines
- What is a Coroutine
- How to run a coroutine
- How to use asyncio.Runner
- Get return value from coroutine
- Run coroutine in the background
- Run coroutine after a delay
- How to sleep() a coroutine
- What is asyncio.sleep(0)
- How to get a task for a coroutine
- How to run coroutine from thread
- Coroutine function types
Task Cancelation
- How to cancel a task
- When are tasks canceled
- Cancelation best practices
- Asyncio force cancel
- Asyncio cancel and wait idiom
- Asyncio Uncancel
- Asyncio task cancels itself
- Propagate CancelledError
- Suppress CancelledError
- Consume CancelledError
Advanced Tasks
- How to wait_for() tasks
- How to shield() tasks
- How to run task in thread
- Run blocking tasks in asyncio
- Asyncio context variables
- Asyncio timeout best practices
- Asyncio daemon tasks
- Kill all asyncio tasks
Groups of Tasks
- How to use gather()
- How to use gather() callbacks
- How to cancel all gather() tasks
- How to wait() for tasks
- How to as_completed() tasks
- Asyncio gather() vs wait()
- How to use asyncio.TaskGroup
- How to use timeout()
- How to use timeout_at()
Async Queues
Async Subprocesses
Asyncio Libraries
ThreadPoolExecutor Learning Path
Python provides thread pool-based concurrency with the “ThreadPoolExecutor” class.
This section provides a learning path that you can use to get started and get effective with the ThreadPoolExecutor class, super fast.
- Step 1: Discover the ThreadPoolExecutor class in Python.
- Step 2: Discover how to run code in the ThreadPoolExecutor.
- Step 3: Discover how to get the most out of ThreadPoolExecutor.
Next, you can browse all tutorials or dive into a topic below to learn more.
Configure
- Configure Max Workers
- How to Configure Thread Names
- Worker Initializer Functions
- How to Use the Context Manager
- How to Shutdown TPE
Common Use Case
Basics
- map() vs. submit()
- wait() vs. as_completed()
- Common Usage Patterns
- Wait For The First Task To Finish
- Wait For All Tasks to Finish
- How To Get Task Results
- How to Check Task Status
- How to Add a Callback to a Task
Intermediate
- Best Practices
- How to Submit All Function Types
- How to Check Thread Names
- Handle Exceptions in Tasks
- Handle Exceptions with Pool
- How to Use With Thread-Local
- Number of Remaining Tasks
- How to Show Progress for Tasks
- Log From Tasks
- How To Stop Running Tasks
- How to Cancel Tasks
- How Does it Work
- How to use Timeouts
- Thread that runs Callbacks
- Tasks that submit Tasks
- When are Workers Started
- Configure map() Chunksize
Comparisons
- ThreadPoolExecutor vs. Thread
- TPE vs ThreadPool
- ThreadPoolExecutor vs. GIL
- ThreadPoolExecutor vs. AsyncIO
- ThreadPoolExecutor vs. PPE
Advanced
- How to Limit Pending Tasks
- How to Retry Failed Tasks
- How to Stop All Tasks if Task Fails
- How to Submit a Follow-up Task
- ThreadPoolExecutor Thread-Safe
- How To Identify Deadlocks
- First Result From Stream of Tasks
- Pipeline for Multi-Step Tasks
- Share Queue With Workers
- Share Data With Workers
- ThreadPoolExecutor Stops Main
- Kill Running Tasks
Failure Modes
Example Applications
ProcessPoolExecutor Learning Path
Python provides process pool-based concurrency with the “ProcessPoolExecutor” class.
This section provides a learning path that you can use to get started and get effective with the ProcessPoolExecutor class, super fast.
- Step 1: Discover the ProcessPoolExecutor class in Python.
- Step 2: Discover how to run code in the ProcessPoolExecutor.
- Step 3: Discover how to get the most out of ProcessPoolExecutor.
Next, you can browse all tutorials or dive into a topic below to learn more.
Configure
- Configure Max Workers
- Config Worker Initialize Function
- How to Use The Context Manager
- Config Multiprocessing Context
- Config Max Tasks Per Child
Basics
- map() vs submit()
- wait() vs as_completed()
- Common Usage Patterns
- How to Wait For The First Result
- How to Wait For a Task to Finish
- How to Get Results
- How to Check the Status of a Task
- How to Add a Callback to a Task
Intermediate
ThreadPool Learning Path
Python provides thread pool-based concurrency with the “multiprocessing.pool.ThreadPool” class.
This section provides a learning path that you can use to get started and get effective with the ThreadPool class, super fast.
- Step 1: Discover the ThreadPool class in Python.
- Step 2: Discover how to run code in the ThreadPool.
- Step 3: Discover how to get the most out of ThreadPool.
Next, you can browse all tutorials or dive into a topic below to learn more.
Basics
- The dummy module
- ThreadPool class
- ThreadPool life-cycle
- Should we use ThreadPool
- Concurrent for-loops
Configure
Intermediate
Advanced
- When are workers started
- Does ThreadPool stop main
- How to get results from async
- Tasks fail silently
- Is ThreadPool slower
- Get num remaining tasks
- ThreadPool exception handling
- Producer-consumer pattern
Callback Functions
Issue Tasks
- Issue tasks with apply
- Issue tasks with apply_async
- Issue tasks with map
- Issue tasks with map_async
- Issue tasks with imap
- Issue tasks with imap_unordered
- Issue tasks with starmap
- Issue tasks with starmap_async
- How to choose a method
- Use map with multiple args
- How to use AsyncResult
- How to configure chunksize
Common Tasks
- ThreadPool best practices
- Common usage patterns
- Common errors
- How to log from tasks
- How to stop all tasks
- Stop all if one task fails
- Issue follow-up tasks
- Wait for all tasks to finish
- How to show progress
- How to get first result
Comparisons
Multiprocessing Pool Learning Path
Python provides process pool-based concurrency with the “multiprocessing.Pool” class.
This section provides a learning path that you can use to get started and get effective with the multiprocessing.Pool class, super fast.
- Step 1: Discover the multiprocessing.Pool class in Python.
- Step 2: Discover how to run code in the multiprocessing.Pool.
- Step 3: Discover how to get the most out of multiprocessing.Pool.
Next, you can browse all tutorials or dive into a topic below to learn more.
Configure
- Config num workers
- Use worker initalizer
- Config max tasks per child
- Config pool context
- How to configure
Basics
- Pool PEP
- Context manager interface
- How to shutdown
- How to join
- Exception Handling
- Pool stop main exiting
- When workers are started
- Workers restarted if killed
- Different function types
Intermediate
- Share global vars
- Stop all tasks
- Kill all tasks
- Get all worker PIDs
- Get all worker names
- Get all thread details
- Tasks fail silently
- Get first result
- Get result from async
- How to share a queue
Advanced
Common Usage
Use with Primitives
Issue Tasks
- Issue tasks with apply
- Issue tasks with apply_async
- Issue tasks with map
- Issue tasks with map_async
- Issue tasks with imap
- Issue tasks with imap_unordered
- Issue tasks with starmap
- Issue tasks with starmap_asyc
- How to choose method
- How to use AsyncResult
- map() multiple arguments
- map() chunksize
Callback Functions
Comparisons
File I/O Concurrency Learning Path
Working with files can be slow.
This section provides a learning path that you can use to get started and get effective at using Python concurrency to speed up file I/O operations, super fast.
- Step 1: Review Python concurrency techniques.
- Step 2: Review Python file I/O operations.
- Step 3: Discover how to perform file I/O concurrently.
Next, you can browse all tutorials or dive into a topic below to learn more.
Read/Write Files
Zip/Unzip Files
NumPy Parallelism Learning Path
NumPy is a third-party library for working with arrays of numbers efficiently.
It is widely used as the basis in other libraries such as SciPy and Pandas and is central to Python’s use in deep learning and machine learning.
This section provides a learning path that you can use to get started and get effective with parallelism in NumPy, super fast.
- Step 1: Discover why NumPy Concurrency is important.
- Step 2: Discover the Cost of a naive approach to NumPy parallelism
- Step 3: Discover how Get The Most Out Of NumPy
- Concurrent NumPy 7-Day Course (or the email course)
- Concurrent NumPy in Python (my book!)
Next, you can browse all tutorials or dive into a topic below to learn more.
NumPy BLAS Threads
- What is NumPy BLAS/LAPACK
- What are NumPy BLAS Libraries
- Install NumPy BLAS Library
- Check NumPy BLAS Library
- Configure NumPy BLAS Threads
- Limit threads with threadpoolctl
NumPy BLAS Parallelism
Multithread NumPy
- NumPy Releases the GIL
- Parallel Array Fill with ThreadPool
- Parallel Array Fill with TPE
- Parallel Element-Wise Math
- Parallel Matrix Math
- Parallel Vector Math
- Parallel Vector Distance
- Parallel Random Numbers
- Faster NumPy with Threads
Share NumPy Arrays
- 9 Ways to Share NumPy Arrays
- Fastest To Share NumPy Array
- Share Array using Queue
- Share Array as Argument
- Share Array using Global Var
- Share Array using ctypes
- Share Array using RawArray
- Share Array using Manager
- Share Array with SharedMemory
- Share Array Memory-Mapped File
Errors to Avoid
Benchmarking Learning Path
Python code can be slow.
We must benchmark our code in order to know how slow it is and whether the changes we have made make it faster or not.
Benchmarking is the way to faster Python code and this learning path will show you how to benchmark your code.
- Step 1: Discover the importance of benchmarking.
- Step 2: Discover how to benchmark code in Python.
- Step 3: Discover how to master the craft of benchmarking.
- Python Benchmarking 7-Day Crash Course (or the email course)
- Python Benchmarking (my book!)
Next, you can browse all tutorials or dive into a topic below to learn more.
Basics
- Benchmark a Statement
- Benchmark a Function
- Benchmark a Program
- 4 Ways to Benchmark
- Microbenchmarking
Time Module Functions
- Benchmark with time()
- Benchmark with perf_counter()
- Benchmark with monotonic()
- Benchmark with thread_time()
- Benchmark with process_time()
- Compare all time functions
- Compare time() vs perf_counter()
Other Benchmarking
- Benchmark with time command
- Books on Benchmarking
- Benchmark Unit Testing
- How to Profile Python Programs
Benchmarking Examples
Best Practices
- Benchmarking Best Practices
- Benchmarking Metrics
- Repeat Benchmarks
- Benchmark Execution Time
- Tips When Presenting Results
Benchmarking Helpers
Benchmark With Timeit
- Benchmark with timeit()
- Benchmark with timeit CLI
- Benchmark with timeit module
- Compare time() and timeit
Benchmark Asyncio
- Asyncio Benchmark Decorator
- Async Benchmark Context Mgmr
- Asyncio Benchmark Coroutine
- Benchmark with loop.time
- Profile Asyncio Programs
- Profile Async With line_profiler
Benchmarking Libraries
Need More Help?
Do you need more help with Python concurrency?
Perhaps you need help with a topic not covered above?
- Contact me directly and I will do my best to help.