Threading and multiprocessing made easy.
Free software: Apache-2.0 license
Documentation: https://lox.readthedocs.io.
Python >=3.6
Lox provides decorators and synchronization primitives to quickly add concurrency to your projects.
Installation
pip3 install –user lox
Features
Multithreading: Powerful, intuitive multithreading in just 2 additional lines of code.
Multiprocessing: Truly parallel function execution with the same interface as multithreading.
Synchronization: Advanced thread synchronization, communication, and resource management tools.
Todos
All objects except lox.process are for threads. These will eventually be multiprocess friendly.
Usage
Easy Multithreading
>>> import lox >>> >>> @lox.thread(4) # Will operate with a maximum of 4 threads ... def foo(x,y): ... return x*y >>> foo(3,4) # normal function calls still work 12 >>> for i in range(5): ... foo.scatter(i, i+1) -ignore- >>> # foo is currently being executed in 4 threads >>> results = foo.gather() # block until results are ready >>> print(results) # Results are in the same order as scatter() calls [0, 2, 6, 12, 20]
Or, for example, if you aren’t allowed to directly decorate the function you would like multithreaded/multiprocessed, you can just directly invoke the decorator:
>>> # Lets say we don't have direct access to this function
... def foo(x, y):
... return x * y
...
>>>
>>> def my_func():
... foo_threaded = lox.thread(foo)
... for i in range(5):
... foo_threaded.scatter(i, i + 1)
... results = foo_threaded.gather()
... # foo is currently being executed in default 50 thread executor pool
... return results
...
This also makes it easier to dynamically control the number of thread/processes in the executor pool. The syntax is a little weird, but this is just explicitly invoking a decorator that has optional arguments:
>>> # Set the number of executer threads to 10
>>> foo_threaded = lox.thread(10)(foo)
Easy Multiprocessing
>>> import lox
>>>
>>> @lox.process(4) # Will operate with a pool of 4 processes
... def foo(x, y):
... return x * y
...
>>> foo(3, 4) # normal function calls still work
12
>>> for i in range(5):
... foo.scatter(i, i + 1)
...
-ignore-
>>> # foo is currently being executed in 4 processes
>>> results = foo.gather() # block until results are ready
>>> print(results) # Results are in the same order as scatter() calls
[0, 2, 6, 12, 20]
Progress Bar Support (tqdm)
>>> import lox
>>> from random import random
>>> from time import sleep
>>>
>>> @lox.thread(2)
... def foo(multiplier):
... sleep(multiplier * random())
...
>>> for i in range(10):
>>> foo.scatter(i)
>>> results = foo.gather(tqdm=True)
90%|████████████████████████████████▌ | 9/10 [00:03<00:00, 1.32it/s]
100%|███████████████████████████████████████| 10/10 [00:06<00:00, 1.46s/it]
History
0.11.0 (2022-04-07)
Set number of workers to 0 (in thread execution) if the environment variable LOX_DEBUG is set to a true-like value (true, 1, etc.). Makes it easier to set breakpoints in multithreaded code without having to manually edit the decorator.
0.10.0 (2021-12-18)
Remove dependency pinning.
Allow @lox.thread(0). This will execute scatter calls in parent thread. Useful for debugging breakpoints in parallelized code.
0.9.0 (2020-11-25)
tqdm support on lox.process.gather. See v0.8.0 release notes for usage.
0.8.0 (2020-11-25)
tqdm support on lox.thread.gather * Can be a bool:
>>> my_func.gather(tqdm=True)
Can be a tqdm object:
>>> from tqdm import tqdm >>> pbar = tqdm(total=100) >>> for _ in range(100): >>> my_func.scatter() >>> my_func.gather(tqdm=pbar)
0.7.0 (2020-07-20)
Complete rework of workers + Fix memory leaks
Drop support for python3.5
Drop support for chaining in favor of simpler codebase
0.6.3 (2019-07-30)
Alternative fix for 0.6.2.
0.6.2 (2019-07-21)
Update dependencies
Fix garbage-collecting exclusiviity
0.6.1 (2019-07-21)
Fix memory leak in lox.process.
0.6.0 (2019-07-21)
lox.Announcement subscribe() calls now return another Announcement object that behaves like a queue instead of an actual queue. Allows for many-queue-to-many-queue communications.
New Object: lox.Funnel. allows for waiting on many queues for a complete set of inputs indicated by a job ID.
0.5.0 (2019-07-01)
New Object: lox.Announcement. Allows a one-to-many thread queue with backlog support so that late subscribers can still get all (or most recent) announcements before they subscribed.
New Feature: lox.thread scatter calls can now be chained together. scatter now returns an int subclass that contains metadata to allow chaining. Each scatter call can have a maximum of 1 previous scatter result.
Documentation updates, theming, and logos
0.4.3 (2019-06-24)
Garbage collect cached decorated object methods
0.4.2 (2019-06-23)
Fixed multiple instances and successive scatter and gather calls to wrapped methods
0.4.1 (2019-06-23)
Fixed broken workers and unit tests for workers
0.4.0 (2019-06-22)
Semi-breaking change: lox.thread and lox.process now automatically pass the object instance when decorating a method.
0.3.4 (2019-06-20)
Print traceback in red when a thread crashes
0.3.3 (2019-06-19)
Fix bug where thread in scatter of lox.thread double releases on empty queue
0.3.2 (2019-06-17)
Fix manifest for installation from wheel
0.3.1 (2019-06-17)
Fix package on pypi
0.3.0 (2019-06-01)
Multiprocessing decorator. lox.pool renamed to lox.thread
Substantial pytest bug fixes
Documentation examples
timeout for RWLock
0.2.1 (2019-05-25)
Fix IndexSemaphore context manager
0.2.0 (2019-05-24)
Added QLock
Documentation syntax fixes
0.1.1 (2019-05-24)
CICD test
0.1.0 (2019-05-24)
First release on PyPI.
Metadata
Release files for lox 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| lox-1.0.0.tar.gz | 37.8 kB | Without provenance | Details for lox-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lox-1.0.0-py2.py3-none-any.whl | Python 3, Python 2 | none | any | Details for lox-1.0.0-py2.py3-none-any.whl |
Total release size: 63.5 kB
Release files / lox-1.0.0.tar.gz
| Download URL | lox-1.0.0.tar.gz |
|---|---|
| Size | 37.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1ff5f9426db2e02d28a5db36029858eefaa6d68af1f91eabd36680d1f363844c
|
|
BLAKE2b-256 checksum How to use checksums |
1b4bd634b9481789c6008ab729c05dc4f0baaeb47f3293a340dc93685f5a2a3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.13
|
Release files / lox-1.0.0-py2.py3-none-any.whl
| Download URL | lox-1.0.0-py2.py3-none-any.whl |
|---|---|
| Size | 25.6 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
d6694e3cbf333c21e254d6490adb69540429bfdd5e12f5fafcb18925e8e687b1
|
|
BLAKE2b-256 checksum How to use checksums |
9978deeeb601b0a477596cc5dad3c26952be2e1d05ab269ac4ac00acf1d37613
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.13
|
Security for lox 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.