Skip to main content

Resource Semaphore

License Python Python Coverage

Resource Semaphore is a typed, high-level synchronization library for managing multiple constrained resources within a single process. It applies backpressure to prevent resource exhaustion.

Standard semaphores guard a single counter of "slots." resource-semaphore extends this to multiple, heterogeneous resources — such as CPU cores, available RAM, disk I/O bandwidth, or worker slots — with a single, atomic acquire/release operation. When capacity is exhausted, callers block until resources become available.

Installation

pip install resource-semaphore

Quick Start

import asyncio
from resource_semaphore import AsyncResourceSemaphore

semaphore = AsyncResourceSemaphore(resources={"db_conn": 2, "ram_mb": 4096})


async def process(data_size_mb: int):
    async with semaphore.claim({"db_conn": 1, "ram_mb": data_size_mb}):
        await do_work()


async def main():
    # Three tasks compete for 2 DB connections: one will wait automatically
    await asyncio.gather(
        process(1024),
        process(1024),
        process(1024),
    )

Features

  • Multi-resource: atomically acquire multiple named resources (e.g. DB connections, RAM, workers) in one call
  • Sync + Async: ResourceSemaphore (threading) and AsyncResourceSemaphore (asyncio) share the same API
  • Fair and Greedy variants: Fair semaphores wake the earliest-arrived request that can currently be satisfied, and let smaller later requests bypass a blocked larger one — see Docs: Fairness and Trade-offs for the starvation trade-off this implies. Greedy semaphores skip ordering entirely and grant to whichever caller wins the race; this can starve a specific waiter indefinitely under sustained contention (see documentation for trade-off details).
  • Timeouts: acquire()/claim() accept an optional timeout argument and raise TimeoutError
  • Safe releases: opaque Ticket objects; releasing an unknown or already-released ticket raises ValueError
  • Typed: generic over resource key types via Literal for compile-time safety
  • No-op variants: NoopResourceSemaphore and AsyncNoopResourceSemaphore for tests that don't need real limits
  • Graceful shutdown: shutdown() wakes all blocked callers with SemaphoreError; further acquire() calls raise immediately, while in-flight tickets acquired prior to shutdown can still be released safely via release() or exiting claim()
  • Zero dependencies in core
  • Optional system utilities: resource-semaphore[utils] wraps psutil for host CPU, RAM, and disk storage discovery (CPU, RAM, and disk storage only — no GPU support)
  • Performance: Fair and Greedy variants show no measurable throughput difference in our benchmarks (see .benchmarks/); Greedy trades ordering guarantees for a simpler code path, not raw speed.

Limitations

  • Single-process only: Manages concurrency within a single Python process (threads or asyncio tasks). It is not a distributed or cross-process semaphore. Note that AsyncResourceSemaphore binds to a single event loop and is not thread-safe across distinct OS threads.
  • Resource discovery limits: Built-in utilities (resource-semaphore[utils]) only discover basic CPU, memory, and disk metrics via psutil. There is no automatic discovery for GPUs, network interfaces, or custom external hardware (though any named resource can be managed by manually specifying integer capacities).
  • No deadlock prevention: Does not detect or prevent application-level deadlocks resulting from improper lock acquisition ordering across multiple semaphores or code paths.
  • Evolving API: The API is subject to refinement; minor version updates may introduce breaking changes as feature needs evolve.

Documentation

For a comprehensive guide on core concepts, initialization, and API usage (including both synchronous and asynchronous context managers), please refer to our documentation:

Examples

We provide runnable scripts demonstrating real-world usage scenarios:

Roadmap

To see what features are planned for future releases and what has already been accomplished, check out our TODO.md tracker.

Metadata

Release files for resource-semaphore 1.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for resource-semaphore 1.4.1
File Size Uploaded Provenance
resource_semaphore-1.4.1.tar.gz 13.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for resource-semaphore 1.4.1
File Interpreter ABI Platform
resource_semaphore-1.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 29.3 kB

Release files / resource_semaphore-1.4.1.tar.gz

Download URL resource_semaphore-1.4.1.tar.gz
Size 13.5 kB
Tags Source
SHA-256 checksum
How to use checksums
2c2b5e0eb90206e306ba87e6477fd908e8efdd22012a0287f9c9aa25a92eeb4b
BLAKE2b-256 checksum
How to use checksums
8aa42b77bdd1bd8c11bbb5b7ad92216e15ce46041902b5eb2bb7d119ca664757
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / resource_semaphore-1.4.1-py3-none-any.whl

Download URL resource_semaphore-1.4.1-py3-none-any.whl
Size 15.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
049ff759ddeab74e8ad9cdbe9df7f9f686916f512320b80f68c666432872b353
BLAKE2b-256 checksum
How to use checksums
8adb8910f6b59190131d1ce74f5fc8d09e5b66eec7766205aa0af2380575b2a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for resource-semaphore 1.4.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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page