Skip to main content

Convenient threading and improved ThreadPoolExecutor

Project description

threadlet

PyPI - Version PyPI - Python Version

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 Future object.
  • Worker is a thread with a loop for executing incoming tasks.
  • SimpleThreadPoolExecutor is a simple variant of concurrent.futures.ThreadPoolExecutor which spawns all the threads at the beginning.
  • ThreadPoolExecutor is an adaptive variant of the concurrent.futures.ThreadPoolExecutor which automatically spawns and shutdowns threads depending on load. One thread in the pool lives forever, new threads are spawned on submit call 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

threadlet-3.2.1.tar.gz (8.7 kB view details)

Uploaded Source

Built Distribution

threadlet-3.2.1-py3-none-any.whl (5.6 kB view details)

Uploaded Python 3

File details

Details for the file threadlet-3.2.1.tar.gz.

File metadata

  • Download URL: threadlet-3.2.1.tar.gz
  • Upload date:
  • Size: 8.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.11.7

File hashes

Hashes for threadlet-3.2.1.tar.gz
Algorithm Hash digest
SHA256 d40b4b6b3a6cf10b78c19a54d25e47ad3f7425ed2adc14593d98d0fd4834be56
MD5 d0fc02b896da3ad89ee1f0e963fe9e33
BLAKE2b-256 1187b2415c4e1ac5a03021a7747eb8672db8cdbebfb19ae439210b7c464550ca

See more details on using hashes here.

File details

Details for the file threadlet-3.2.1-py3-none-any.whl.

File metadata

  • Download URL: threadlet-3.2.1-py3-none-any.whl
  • Upload date:
  • Size: 5.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.11.7

File hashes

Hashes for threadlet-3.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ede3bd855d215fefa4fac90b164439fcc40f699c614d50a26c5bd598ffdaaebc
MD5 442b8f3038487e7d230a155ebdd0b46b
BLAKE2b-256 9b690f25e09d402bfb432574f1ace8c607032a9c35f01dc37823c6ef1a1702c1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page