Skip to main content

Cross-platform, cross-process shared memory with rwlock and SPSC ring buffer for Python, powered by Rust

Project description

membridge

PyPI Python License: MIT CI

Cross-platform, cross-process shared memory for Python — backed by Rust via PyO3.

membridge provides two communication primitives over a named shared memory segment:

Primitive Use case
MappedView Sequential read / write with a built-in cross-process reader-writer lock
SpscRingBuffer Lock-free single-producer / single-consumer message queue

Both primitives work identically on Linux, macOS, and Windows.


Platform support

Platform Shared memory backend
Linux / macOS shm_open + ftruncate + mmap (POSIX)
Windows CreateFileMappingA + MapViewOfFile (Win32)

Installation

pip install membridge

Requires Python ≥ 3.10. Pre-built wheels are available for Linux (x86_64, aarch64), macOS (universal2), and Windows (x86_64).


Quick start

MappedView — sequential shared memory with rwlock

# process A: producer
import membridge

mem  = membridge.SharedMemory.create("/demo", 4096)
view = mem.map()

view.write("Hello from A!")   # str → length-prefixed UTF-8
view.write(42)                # int → i64
view.write(3.14)              # float → f64
view.write(True)              # bool → u8
# process B: consumer
import membridge

mem  = membridge.SharedMemory.open("/demo")   # size auto-detected on Unix
view = mem.map()

msg   = view.read("str")    # → "Hello from A!"
count = view.read("int")    # → 42
ratio = view.read("float")  # → 3.14
flag  = view.read("bool")   # → True

membridge.SharedMemory.remove("/demo")

SpscRingBuffer — lock-free message queue

# producer
import membridge

mem  = membridge.SharedMemory.create("/spsc", 1024 + 24)
ring = mem.spsc()

ring.push("msg-0")
ring.push(["Hello", 0.92, True])   # heterogeneous list in one message
ring.push("__EOF__")
# consumer
import time, membridge

mem  = membridge.SharedMemory.open("/spsc", 1024 + 24)
ring = mem.spsc()

while True:
    msg = ring.pop("str")
    if msg is not None:
        print(msg)
        if msg == "__EOF__":
            break
    else:
        time.sleep(0.01)

membridge.SharedMemory.remove("/spsc")

API reference

SharedMemory

SharedMemory.create(name: str, size: int) -> SharedMemory
SharedMemory.open(name: str, size: int | None = None) -> SharedMemory
SharedMemory.remove(name: str) -> None

mem.map()  -> MappedView
mem.spsc() -> SpscRingBuffer
mem.name() -> str
mem.size() -> int

Names must start with '/', e.g. "/my_segment".
On Windows, size must be passed explicitly to open().
On Unix, remove() calls shm_unlink; on Windows it is a no-op.


MappedView

The segment layout reserves 4 bytes at offset 0 for the rwlock header. All user-facing offsets are relative to the data area that follows.

view.write(data, offset=None)                    # write one value
view.write_mixed(items, offset=None)             # write a heterogeneous list
view.read(tag: str)        -> Any                # read one typed value
view.read_mixed(schema, offset=None) -> list     # read multiple typed values
view.read_range(offset, length) -> bytes
view.read_all()            -> bytes
view.seek(pos: int = 0)
view.tell()                -> int
view.zero()                                      # zero the data area
view.size()                -> int                # data area size (total - 4)
view.reader_count()        -> int
view.is_write_locked()     -> bool

Supported types for write / read

Python type Stored as Bytes
bool u8 (0 or 1) 1
int i64 8
float f64 8
str u32 length prefix + UTF-8 4 + len
bytes / bytearray raw bytes len

Type tags for read / read_mixed

"bool", "int" / "i64", "float" / "f64", "f32", "i32", "u8", "u32", "u64", "str"

write_mixed / read_mixed example

# write
view.write_mixed([
    ["Hello", "from", "producer"],   # 3 × str
    [0.92, 0.87, 0.95],              # 3 × float
    [True, False, True],             # 3 × bool
])

# read
labels, scores, flags = view.read_mixed([
    ("str",   3),
    ("float", 3),
    ("bool",  3),
])

SpscRingBuffer

ring.push(data) -> bool          # False = buffer full, retry later
ring.pop(tag=None) -> Any | None # None = buffer empty
ring.pop_mixed(schema) -> list | None

ring.used()     -> int
ring.free()     -> int
ring.capacity() -> int
ring.is_empty() -> bool
ring.is_full()  -> bool

Memory layout

[ head (8 B) | tail (8 B) | capacity (8 B) | data (capacity B) ]

The data capacity (size - 24) must be a power of two.
Use size = N + 24 where N is a power of two, e.g. 1024 + 24 = 1048.

push / pop_mixed example

ring.push(["Normal", 0.92, True])

label, score, flag = ring.pop_mixed([
    ("str",   1),
    ("float", 1),
    ("bool",  1),
])

Memory layout overview

SharedMemory segment
├── MappedView
│   ├── [0..4)   ShmRwLock  (AtomicI32)
│   └── [4..)   user data
│
└── SpscRingBuffer
    ├── [0..8)   head       (AtomicUsize)
    ├── [8..16)  tail       (AtomicUsize)
    ├── [16..24) capacity   (usize, written once)
    └── [24..)   ring data  (power-of-two bytes)

Examples

The examples/ directory contains ready-to-run scripts:

Script Description
single_process.py Write and read back in one process
producer.py / consumer.py Two-process MappedView demo
spsc_producer.py / spsc_consumer.py Two-process SPSC ring buffer demo

Run the two-process demos by starting the producer in one terminal and the consumer in another:

python examples/producer.py   # terminal 1
python examples/consumer.py   # terminal 2

Building from source

Rust and maturin are required.

pip install maturin
maturin develop          # install into the current virtualenv (debug build)
maturin build --release  # produce a wheel in ./dist/

License

MIT — see 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 Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

membridge-1.0.0-cp310-abi3-win_amd64.whl (161.1 kB view details)

Uploaded CPython 3.10+Windows x86-64

membridge-1.0.0-cp310-abi3-manylinux_2_28_aarch64.whl (306.0 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

membridge-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (306.4 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

membridge-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (520.4 kB view details)

Uploaded CPython 3.10+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file membridge-1.0.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: membridge-1.0.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 161.1 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for membridge-1.0.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c3eaa5e803b2f591a50764440213c87730373cb6c328efc8a915442012e7c0ca
MD5 e4902df8c07e4c1d1024e675e5a4b6e5
BLAKE2b-256 99f36cdf4325af305093e82d396b3094cbe157d644e084983f0352616eb86521

See more details on using hashes here.

Provenance

The following attestation bundles were made for membridge-1.0.0-cp310-abi3-win_amd64.whl:

Publisher: ci.yml on ParrotXray/membridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file membridge-1.0.0-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for membridge-1.0.0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 688f1d55968093a655616fe4ceddeb4393e6f08a60abfcb5c22a427aff7e7593
MD5 b010ac72349984c0ee37c7345a7429ff
BLAKE2b-256 d5f7f37747cd40aea826b75eda5802cfe15b7b5fb64a05870a16bcd9ece7704c

See more details on using hashes here.

Provenance

The following attestation bundles were made for membridge-1.0.0-cp310-abi3-manylinux_2_28_aarch64.whl:

Publisher: ci.yml on ParrotXray/membridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file membridge-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for membridge-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a6c33464b1663705287959525c40c6c06408d03e8fd80a832e5aa7731dea8ce5
MD5 52bc82f1cb7f26c0b38aac6408084f5d
BLAKE2b-256 92695b2ec6cf9531f58c700d5b77c35f8eae45ac22911d75f4dfe03f3d3cb781

See more details on using hashes here.

Provenance

The following attestation bundles were made for membridge-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on ParrotXray/membridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file membridge-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for membridge-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 0b23fcc73014a67a0fe8579d1b0c54b0f3b65979c36b2458bfd88ff40a2eafc6
MD5 9d6aa32ed994fecbbcf97f55b344c597
BLAKE2b-256 7a77b398639d73cea543055e925e0cf83ddcdc56da3c443d1bb679da6aa52000

See more details on using hashes here.

Provenance

The following attestation bundles were made for membridge-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: ci.yml on ParrotXray/membridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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