threadlet
More convenient threads and pools with futures.
from threadlet import spawn, go
def plus2(n):
return n + 2
# run function in thread
future = spawn(plus2, 1)
assert future.result() == 3
# run function in adaptive thread pool executor
future = go(plus2, 2)
assert future.result() == 4
- spawn is a helper which runs function in a separate thread and returns
Future. - go is a similar helper, but runs function in adaptive thread pool executor which is handled in background.
- Task is a wrapper for encapsulating a function, its arguments and
Futureobject. - Worker is a thread with a loop for executing incoming tasks.
- SimpleThreadPoolExecutor is a simple variant of
concurrent.futures.ThreadPoolExecutorwhich spawns all the threads at the beginning. - ThreadPoolExecutor is an adaptive variant of the
concurrent.futures.ThreadPoolExecutorwhich automatically spawns and shutdowns threads depending on load. One thread in the pool lives forever, new threads are spawned onsubmitcall if there are no idle threads and die after some idle time(1 second by default).
Table of Contents
Installation
pip install threadlet
Usage
import threading
from threadlet import (
spawn,
go,
Future,
Task,
Worker,
SimpleThreadPoolExecutor,
ThreadPoolExecutor,
)
def calc(x):
return x * 2
# execute function in an adaptive thread pool executor
# which is going to be started automatically at first `go` call and shut down at application exit
future = go(calc, 2)
assert future.result() == 4
# is equivalent to:
with ThreadPoolExecutor() as tpe:
future = tpe.submit(calc, 2)
assert future.result() == 4
# execute function in a separate thread:
future = spawn(calc, 2)
assert future.result() == 4
# is equivalent to:
task = Task(Future(), calc, [2], {})
threading.Thread(target=task.run).start()
assert task.future.result() == 4
# spawns one thread(worker) to sequentially handle all submitted functions
with Worker() as w:
f1 = w.submit(calc, 3)
f2 = w.submit(calc, 4)
assert f1.result() == 6
assert f2.result() == 8
# spawns 4 threads(workers) to handle all tasks in parallel
with SimpleThreadPoolExecutor(4) as tpe:
future = tpe.submit(calc, 5)
assert future.result() == 10
Benchmarks
- submit: submits 1 million futures.
- e2e[N] (end to end[N workers]): submits 1 million futures using N workers and consumes results in a separate thread.
concurrent.futures.thread.ThreadPoolExecutor submit: time=12.94s size=0.04mb, peak=43.61mb
threadlet.ThreadPoolExecutor submit: time= 2.89s size=0.04mb, peak=20.35mb
threadlet.SimpleThreadPoolExecutor submit: time= 2.72s size=0.04mb, peak=24.49mb
concurrent.futures.thread.ThreadPoolExecutor e2e[1]: time=15.80s size=0.04mb, peak=28.56mb
threadlet.ThreadPoolExecutor e2e[1]: time= 4.32s size=0.02mb, peak=19.48mb
threadlet.SimpleThreadPoolExecutor e2e[1]: time= 4.23s size=0.02mb, peak=26.45mb
concurrent.futures.thread.ThreadPoolExecutor e2e[2]: time=33.36s size=0.07mb, peak=32.00mb
threadlet.ThreadPoolExecutor e2e[2]: time= 4.35s size=0.02mb, peak=35.83mb
threadlet.SimpleThreadPoolExecutor e2e[2]: time= 4.18s size=0.02mb, peak=41.81mb
concurrent.futures.thread.ThreadPoolExecutor e2e[4]: time= 7.49s size=0.11mb, peak=42.97mb
threadlet.ThreadPoolExecutor e2e[4]: time= 4.37s size=0.03mb, peak=28.21mb
threadlet.SimpleThreadPoolExecutor e2e[4]: time= 4.30s size=0.02mb, peak=39.81mb
concurrent.futures.thread.ThreadPoolExecutor e2e[8]: time= 7.30s size=0.21mb, peak=41.04mb
threadlet.ThreadPoolExecutor e2e[8]: time= 4.49s size=0.05mb, peak=29.20mb
threadlet.SimpleThreadPoolExecutor e2e[8]: time= 4.18s size=0.03mb, peak=38.36mb
License
threadlet is distributed under the terms of the MIT license.
Metadata
Release files for threadlet 3.2.1
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 |
|---|---|---|---|---|
| threadlet-3.2.1.tar.gz | 8.7 kB | Without provenance | Details for threadlet-3.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| threadlet-3.2.1-py3-none-any.whl | Python 3 | none | any | Details for threadlet-3.2.1-py3-none-any.whl |
Total release size: 14.4 kB
Release files / threadlet-3.2.1.tar.gz
| Download URL | threadlet-3.2.1.tar.gz |
|---|---|
| Size | 8.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d40b4b6b3a6cf10b78c19a54d25e47ad3f7425ed2adc14593d98d0fd4834be56
|
|
BLAKE2b-256 checksum How to use checksums |
1187b2415c4e1ac5a03021a7747eb8672db8cdbebfb19ae439210b7c464550ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.0 CPython/3.11.7
|
Release files / threadlet-3.2.1-py3-none-any.whl
| Download URL | threadlet-3.2.1-py3-none-any.whl |
|---|---|
| Size | 5.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ede3bd855d215fefa4fac90b164439fcc40f699c614d50a26c5bd598ffdaaebc
|
|
BLAKE2b-256 checksum How to use checksums |
9b690f25e09d402bfb432574f1ace8c607032a9c35f01dc37823c6ef1a1702c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.0 CPython/3.11.7
|
Security for threadlet 3.2.1
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.