前言 / Introduction
隨著 Python 3.14 的正式發布,多線程開發的限制,也隨著下面的改動迎刃而解:
- Free-threaded mode (PEP 703),
- Isolated interpreters (PEP 684),
- And the new InterpreterPoolExecutor (PEP 734),
Python can now run true parallel CPU-bound code directly — even within the same process.
下面將展示一些 Example
- Async I/O
- CPU-bound parallelism
- Multicore execution with interpreter pools
1. Classic Problem: Async + CPU Work
如果你遇到需要
- You fetch data from multiple APIs (I/O-bound)
- Then process, analyze, or compress the data (CPU-bound)
在 Python 3.14 之前
asynciohandled I/O efficiently- CPU work blocked the event loop
- You needed multiprocessing or third-party libs
但現在,你可以混用 async + CPU parallelism ,就能清楚的執行。
Example: Async Fetch + CPU Processing (Python 3.14)
import asyncio
from concurrent.futures import InterpreterPoolExecutor
import aiohttp
import hashlib
# CPU-bound task
def compute_hash(data: str):
h = hashlib.sha256()
h.update(data.encode("utf-8"))
return h.hexdigest()
# I/O-bound async task
async def fetch_content(session, url):
async with session.get(url) as resp:
return await resp.text()
async def main():
urls = [
"https://httpbin.org/uuid",
"https://httpbin.org/get",
"https://httpbin.org/headers",
]
async with aiohttp.ClientSession() as session:
contents = await asyncio.gather(
*[fetch_content(session, url) for url in urls]
)
# Run CPU-bound processing in parallel interpreters
with InterpreterPoolExecutor() as executor:
loop = asyncio.get_running_loop()
results = await asyncio.gather(
*[loop.run_in_executor(executor, compute_hash, c) for c in contents]
)
print(results)
asyncio.run(main())
- Fully async I/O
- True parallel execution for CPU-bound work
- No multiprocessing boilerplate
- No shared GIL blocking
2. Parallel CPU Tasks Without Multiprocessing
在 Python 3.14之前,只能透過 multiprocessing.Process or ProcessPoolExecutor 去多核執行,這將涉及 IPC 和 Pickling。
但現在你可以透過 InterpreterPoolExecutor:
from concurrent.futures import InterpreterPoolExecutor
def heavy_calc(n):
total = 0
for i in range(n):
total += (i * i) % 7
return total
if __name__ == "__main__":
tasks = [50_000_000, 60_000_000, 70_000_000, 80_000_000]
with InterpreterPoolExecutor() as executor:
futures = [
executor.submit(heavy_calc, size)
for size in tasks
]
results = [f.result() for f in futures]
print(results)
- Runs across multiple CPU cores
- No GIL contention
- Same process, cleaner API than multiprocessing
3. Migrating Existing Code
如果你正面臨:
- ThreadPoolExecutor → No speedup for CPU tasks before
- multiprocessing → Heavyweight but necessary
- asyncio → Only useful for I/O
現在你可以逐步地取代舊的方法。
ThreadPoolExecutor (old CPU-bound):
from concurrent.futures import ThreadPoolExecutor
# CPU-bound work = No real speedup
InterpreterPoolExecutor (new and parallel):
from concurrent.futures import InterpreterPoolExecutor
# Runs in parallel across cores
4. Real Use Cases That Now Improve
這邊分享我平時的一些案例:
- Image Processing
- Process multiple images in parallel without subprocess overhead.
- Hashing, Encryption, Compression
- Perfect match for InterpreterPoolExecutor.
- Data Science & ETL Pipelines
- Async I/O + CPU-bound transforms can run together.
- Log Parsing & Report Generation
- Parallel parsing while streaming results.
- Web Scraping + Analysis
- Use aiohttp + free-threaded CPU workers.
5. What About Libraries and Extensions?
Not all libraries are thread-safe under free-threaded mode yet. But support is growing, especially for:
Cythonpybind11nanobindPyO3- NumPy (ongoing work)
Extension modules will need updates to be fully compatible, but Python 3.14 allows them to adopt free-threading gradually.
6. Should You Switch Now?
| Python Version | GIL Status | CPU Parallelism | Recommended Use |
|---|---|---|---|
| ≤ 3.11 | Always on | ❌ No | Legacy / stable only |
| 3.12 | On | ⚠️ Prep stage | Interpreters isolated |
| 3.13 | Optional via build | ✅ Yes | Test and experiment |
| 3.14 | Improved + practical | ✅ Yes | Real use cases begin |
嘗試在一些地方去替換新的 Tools,而不需要全部重寫。
Takeaways
Python 3.14 enables true multicore execution using InterpreterPoolExecutor.
You can now combine async I/O and parallel CPU tasks in one process.
Free-threaded mode (PEP 703) makes threads useful for CPU work.
This becomes the practical replacement for multiprocessing in many workloads.
Extension libraries are gradually adapting but you can start now.