Skip to main content

Convenient threading with futures

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 dies 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.0.tar.gz (8.7 kB view details)

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: threadlet-3.2.0.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.0.tar.gz
Algorithm Hash digest
SHA256 7f0b0e8b84278f8561981ab2bcf294764bdf0b409d3261ebbd609260a6b818dc
MD5 a1e5aa9de4a4c3031c6df8599e27fba8
BLAKE2b-256 5b36e1175e19b8bfa7dcb99696666bef2d12ae1b143d1283be5d181c007637d1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: threadlet-3.2.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a43bcb6b86d7044b483b1b753b75514cd868b6e2a520ca43f1b7eea30e086073
MD5 f7e2a3997aacc5d2ae4f47b975ab1fe2
BLAKE2b-256 30a659a8978e79221c62b3f97d8a788a4003942235f142015ce0f71b4451ed44

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