Basic Concepts
Process
A process has multiple threads. Processes have independent memory spaces, and inter-process communication is relatively convenient.
Thread
The smallest indivisible unit.
Coroutine
Controlled and scheduled by some scheduler.
Blocking vs Non-blocking
This describes the program’s state while it waits for a call result (a message or return value). Both blocking and non-blocking I/O can be synchronous; I/O becomes asynchronous only when the relevant APIs are used.
Asynchronous vs Synchronous
This describes the communication mechanism. A synchronous call returns a result immediately or waits for one. An asynchronous call returns before the result is available; the called function later notifies the caller or invokes a callback.
GIL
pass
Performance Notes
- Multi-threading, multi-processing (single-machine multi-process, multi-machine multi-process)
- Multi-processing can be done directly with multiprocess or by starting multiple Python processes from the shell
- Distributed approach
- Directly use gevent’s monkey patch (coroutine)
- Write extensions, use ctypes to write C libraries called by Python, or write Rust extensions
- Switch interpreters. PyPy can reportedly execute code up to 6.3 times faster, but this is not always practical because library implementations and dependencies differ.
Parallel Programming
Theory is useful, but the examples below are more concrete.
Thread
MultiThread
Generally speaking, just inherit from threading.Thread directly
|
Thread Pool
Not recommended, use process pool instead
- Approach 1, use
ThreadPoolfrom theconcurrentmodule
|
- Approach 2, use
ThreadPoolExecutorfrom theconcurrentmodule withwith
|
- Approach 3, use
ThreadPoolfrom thegeventlibrary
|
Process
MultiProcess
|
ProcessPool
- Approach 1, use
Poolfrom themultiprocessingmodule
|
- Approach 2, use
Poolfrom themultiprocessingmodule with context managerWith
|
- Approach 3, use
ProcessPoolExecutorfrom theconcurrentmodule withwith
|
Coroutine
Use gevent’s monkey patch as early as possible, at the very beginning of the code. No need to modify other code to achieve acceleration.
|
I do not use the other approaches often and am not yet familiar enough with them to cover them here. I will add more as I learn.
Other
Queue:
- queue: A synchronized queue class
# demo code from https://docs.python.org/3/library/queue.html |
- multiprocessing.Queue: Implements all the methods of
queue.Queueexcept fortask_doneandjoin
|
Other
I will cover the GIL, communication in parallel programs, and inter-process communication in more detail in the next post.
References
- How to understand the difference between blocking/non-blocking and synchronous/asynchronous?
- Linux IO modes and detailed explanation of select, poll, epoll
- Parallel Programming with Python.pdf
- What is Python’s GIL, how is multi-threading performance really
- Python Parallel Programming Cookbook.pdf
- Coroutines Python
- Python Parallal Programming
- multiprocessing doc
- Understanding the python GIL
- Multiprocessing Queue Source Code
- queue source code