Skip to main content
Version: Next

Shared Memory Transport

SharedMemoryBackend (via SharedMemoryTransport underneath) uses the OS shared-memory mechanism (multiprocessing.shared_memory) for zero-copy communication between processes on the same machine.

Data is written directly to physical RAM addresses mapped as NumPy arrays. No serialisation, no copying, no kernel bypass — just a pointer to the same address.

How it works​

Process A (plant)             Physical RAM              Process B (controller)
───────────────────── ┌──────────────────────┐ ──────────────────────────
broker.publish(...) ───▶│ [y0, y1, ..., u0] │◀──── broker.read(...)
└──────────────────────┘
"ctrl_bus" (OS name)

Usage with MessageBroker​

from synapsys.broker import MessageBroker, Topic, SharedMemoryBackend
import numpy as np

topic_y = Topic("plant/y", shape=(2,)) # plant output — 2 floats
topic_u = Topic("plant/u", shape=(1,)) # control signal — 1 float

# Owner process: creates the block (create=True)
broker = MessageBroker()
broker.declare_topic(topic_y)
broker.declare_topic(topic_u)
broker.add_backend(SharedMemoryBackend("ctrl_bus", [topic_y, topic_u], create=True))

broker.publish("plant/y", np.zeros(2))
broker.publish("plant/u", np.zeros(1))

# Other processes: connect by name (create=False)
broker2 = MessageBroker()
broker2.declare_topic(topic_y)
broker2.declare_topic(topic_u)
broker2.add_backend(SharedMemoryBackend("ctrl_bus", [topic_y, topic_u], create=False))

y = broker2.read("plant/y")
Owner is responsible for unlink

Only the create=True process releases memory in the OS on close. Client processes call only broker.close().

Multiple agents on the same block​

With MessageBroker, a single broker instance is shared by all agents in the same process — no need for multiple transport handles:

from synapsys.broker import MessageBroker, Topic, SharedMemoryBackend
from synapsys.agents import PlantAgent, ControllerAgent, SyncEngine, SyncMode

topic_y = Topic("plant/y", shape=(1,))
topic_u = Topic("plant/u", shape=(1,))

broker = MessageBroker()
broker.declare_topic(topic_y)
broker.declare_topic(topic_u)
broker.add_backend(SharedMemoryBackend("ctrl_bus", [topic_y, topic_u], create=True))

broker.publish("plant/y", np.zeros(1))
broker.publish("plant/u", np.zeros(1))

plant_agent = PlantAgent(
"plant", plant_d, None, SyncEngine(SyncMode.WALL_CLOCK, dt=0.01),
channel_y="plant/y", channel_u="plant/u", broker=broker,
)
ctrl_agent = ControllerAgent(
"ctrl", law, None, SyncEngine(SyncMode.WALL_CLOCK, dt=0.01),
channel_y="plant/y", channel_u="plant/u", broker=broker,
)
Race conditions

There is no mutex in the current implementation. Architect your topics so that each agent is the sole writer of its topic.

API Reference​

See the full reference at synapsys.transport — SharedMemoryTransport.