aiomultiprocess
aiomultiprocess is a Python library that provides an asynchronous version of the standard `multiprocessing` module, combining the benefits of `asyncio` for I/O-bound tasks and `multiprocessing` for CPU-bound tasks. It runs a full `asyncio` event loop on each child process, enabling high levels of concurrency and parallelism beyond the Global Interpreter Lock (GIL). The library is actively maintained, with its current version being 0.9.1.
Warnings
- breaking By default, aiomultiprocess uses 'spawned' processes on all platforms, which is different from the standard `multiprocessing` module's default 'forked' on Linux/macOS (for Python versions prior to 3.8). This means any objects or coroutines passed to child processes *must* be pickleable (importable from a fresh child process). Unpickleable objects will cause errors.
- gotcha Global variables and shared state behave differently with spawned processes. Each child process gets its own independent memory space; changes to global variables in one process are not reflected in others. This can lead to unexpected behavior if not accounted for.
- gotcha Exceptions raised within worker processes are automatically caught and re-raised in the main process as `ProxyException` objects. While convenient, this might obscure the original traceback or prevent in-worker exception handling (e.g., for logging or reporting).
- gotcha Long-running tasks or high concurrency with `aiomultiprocess.Pool` can sometimes lead to 'OSError: [Errno 24] Too many open files' or memory leaks if worker processes are not periodically refreshed.
- gotcha If you are using an alternative `asyncio` event loop implementation (e.g., `uvloop`), `aiomultiprocess` will not automatically use it in child processes. The default `asyncio` loop will be used instead, potentially leading to suboptimal performance.
Install
-
pip install aiomultiprocess
Imports
- Pool
from aiomultiprocess import Pool
- Process
from aiomultiprocess import Process
- Worker
from aiomultiprocess import Worker
Quickstart
import asyncio
from aiohttp import ClientSession
from aiomultiprocess import Pool
async def fetch_url_content(url: str) -> str:
"""An example async coroutine to be run by the pool."""
async with ClientSession() as session:
async with session.get(url) as response:
response.raise_for_status() # Raise an exception for bad status codes
return await response.text()
async def main():
urls = [
"https://www.google.com",
"https://www.python.org",
"https://docs.python.org/3/library/asyncio.html",
"https://www.wikipedia.org"
]
print(f"Fetching {len(urls)} URLs using aiomultiprocess Pool...")
async with Pool(processes=2) as pool: # Use 2 processes for demonstration
# Use pool.map to apply the coroutine to each URL
async for result in pool.map(fetch_url_content, urls):
if result: # Check if result is not None (e.g., if an exception was caught by handler)
print(f"Fetched content size: {len(result)} bytes for one URL.")
else:
print("Failed to fetch content for a URL.")
if __name__ == '__main__':
# Ensure aiohttp is installed for this example: pip install aiohttp
try:
asyncio.run(main())
except ImportError:
print("Please install aiohttp for this example: pip install aiohttp")
except Exception as e:
print(f"An error occurred: {e}")