Registry / workflow / billiard

billiard

JSON →
library4.2.4pypypi✓ verified 26d ago

billiard is a robust fork of the Python 2.7 `multiprocessing` package, actively maintained by the Celery project. It provides numerous improvements and bugfixes over the standard library's `multiprocessing` module, offering enhanced process-based parallelism for Python applications. It aims to address specific challenges and performance bottlenecks, particularly in distributed task queue systems like Celery, where it serves as a core dependency. The library is under active development with a consistent release cadence.

pip install billiard
INSTALL
IMPORT
SIG · BILLIARD
B
billiard
workflowpythonv4.2.4
Install
1.7s avg
Import
58ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v4.2.4 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.062s · 18.4MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.054s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Process
from billiard import Process
Queue
from billiard import Queue
Pool
from billiard import Pool
from multiprocessing import Pool
While `billiard` is a fork of `multiprocessing`, importing directly from `multiprocessing` will use the standard library version, not `billiard`'s improved version. Explicitly import from `billiard` to use its features.

This quickstart demonstrates how to create and use a process pool with `billiard.Pool` to execute a function across multiple processes. The `if __name__ == '__main__':` guard is essential for proper functioning, especially on Windows and with certain start methods, to prevent infinite process spawning.

import os from billiard import Pool def worker_function(x): """A simple function to be executed by pool workers.""" print(f"Worker PID {os.getpid()}: Processing {x}") return x * x if __name__ == '__main__': # It's crucial to use the if __name__ == '__main__': guard # especially on Windows or when using 'spawn' start methods. print(f"Main process PID: {os.getpid()}") with Pool(processes=3) as pool: # Map the worker_function to a list of inputs results = pool.map(worker_function, range(5)) print(f"Results: {results}") # Alternatively, you can explicitly close and join the pool # pool = Pool(processes=2) # async_result = pool.apply_async(worker_function, (10,)) # print(f"Async result: {async_result.get()}") # pool.close() # pool.join()
Debug
Known issues
breakingPython 3.7 or newer is now required. Older Python versions (e.g., Python 3.6 and earlier) are no longer supported since `billiard` v4.0.0.
fix
Upgrade your Python environment to 3.7 or higher.
affects: >=4.0.0
breakingOn macOS, `billiard` (like `multiprocessing` in Python 3.8+) defaults to the 'spawn' start method instead of 'fork' for safety. Relying on the 'fork' method, particularly in multi-threaded contexts, can lead to crashes.
fix
Ensure your code is 'spawn'-safe (i.e., doesn't rely on inherited state, and uses the `if __name__ == '__main__':` guard). If 'fork' is strictly necessary and you understand the risks, configure the start method explicitly (e.g., `billiard.set_start_method('fork')`).
affects: >=4.3.0rc1 (future), effectively >=4.0.0 (due to underlying Python changes)
gotchaThe `if __name__ == '__main__':` block is critical for any code using `billiard` processes. Without it, especially on Windows or when using 'spawn' or 'forkserver' start methods, child processes will re-import the main module and can lead to infinite recursion and process spawning.
fix
Always wrap the code that creates `Process` or `Pool` objects and their associated logic within an `if __name__ == '__main__':` block.
affects: All versions
gotchaAvoid using the standard `multiprocessing` module within Celery tasks that are managed by `billiard` (Celery's default). This can lead to nested process creation, which may cause unexpected behavior and issues.
fix
If parallel execution is needed within a Celery task, consider restructuring the workflow to use Celery's native group/chain/chord primitives or ensure that any internal parallelization is carefully managed to avoid conflicts with `billiard`'s process management.
affects: All versions
deprecated`SIGUSR2` was removed from `TERMSIGS_DEFAULT`, which defines signals that terminate processes. This change might affect custom signal handling logic.
fix
Review any custom signal handling logic and remove reliance on `SIGUSR2` for process termination if you are using `billiard`'s default signal sets.
affects: >=4.2.1
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'billiard'
The 'billiard' library is not installed in the current Python environment, or the environment is not correctly activated, preventing the Python interpreter from finding the package.
fix
Install the 'billiard' library using pip: `pip install billiard` or `pip3 install billiard` if you have multiple Python versions.
TypeError: can't pickle _thread.lock objects
This error occurs when attempting to pass non-serializable objects (like _thread.lock objects, local functions, or complex stateful class instances) between processes. The 'billiard' library, like 'multiprocessing', uses pickling to transfer objects for certain process start methods (e.g., 'spawn' on Windows or for `Pool` arguments).
fix
Ensure that all objects passed to 'billiard' processes (e.g., as arguments to a `Process` target function or elements in a `Queue`) are picklable. This often involves defining functions at the top level of a module, making classes and their methods independently picklable, or restructuring the data to remove unpicklable components.
AssertionError: daemonic processes are not allowed to have children
A daemon process (a background process that exits when its parent does, commonly used by `billiard` pools and Celery workers) is attempting to create its own child processes. Python's `multiprocessing` and `billiard` modules prevent this to avoid creating orphaned processes.
fix
Redesign the application to avoid nesting process creation. If a background task needs to perform concurrent operations, it should use threads instead of creating new processes. In a Celery context, this means ensuring your tasks do not themselves invoke `billiard.Process` or `multiprocessing.Process`.
billiard.exceptions.WorkerLostError: Worker exited prematurely:
A `billiard` worker process, frequently seen in Celery deployments, terminated unexpectedly. This can be caused by unhandled exceptions within a task, the worker exceeding its allocated memory (killed by the operating system's OOM killer), hitting a hard or soft time limit, or receiving a termination signal.
fix
Inspect detailed worker logs for the specific exception or signal that led to the premature exit. Increase system memory or adjust resource limits if out-of-memory errors are indicated. Implement robust error handling within your tasks and configure Celery's `task_soft_time_limit` and `task_time_limit` settings appropriately.
Upgrade
Version history
4.2.4latest on PyPI · released Nov 30, 2025
Audit
Dependencies
psutiloptionalRequired for `max_memory_per_child` functionality, especially on Windows.
Agent activity
35 hits · last 30 days
node
30
OpenAI (training)
1
Resources
billiard — pip install billiard · libregistry