To those that replied Thank you and to any that follow, I found this:- It works in this test code and it remains to be seen if it works in my application. It is very fast too, it has gone from 100's milliseconds to a few microseconds.
from multiprocessing import Process, Lock, Value, shared_memory
import time
import numpy as np
import signal
import os
class Niao:
def __init__(self, axle_angle, position_x, position_y, energy, speed):
self.axle_angle = axle_angle
self.position_x = position_x
self.position_y = position_y
self.energy = energy
self.speed = speed
def move(self, new_x, new_y):
self.position_x.value = new_x
self.position_y.value = new_y
class SharedWorld:
def __init__(self):
self.lock = Lock()
self.niao_shm = None # Shared memory for Niao attributes
def create_niao_shared_memory(self):
# Create shared memory for Niao attributes
self.niao_shm = shared_memory.SharedMemory(create=True, size=5 * 8) # 5 double values (8 bytes each)
return self.niao_shm
def add_niao(self, niao):
with self.lock:
# Store values in shared memory
shm_array = np.ndarray((5,), dtype='d', buffer=self.niao_shm.buf)
shm_array[0] = niao.axle_angle.value
shm_array[1] = niao.position_x.value
shm_array[2] = niao.position_y.value
shm_array[3] = niao.energy.value
shm_array[4] = niao.speed.value
def get_niao(self):
with self.lock:
shm_array = np.ndarray((5,), dtype='d', buffer=self.niao_shm.buf)
return Niao(
Value('d', shm_array[0]), # Create new Value object
Value('d', shm_array[1]), # Create new Value object
Value('d', shm_array[2]), # Create new Value object
Value('d', shm_array[3]), # Create new Value object
Value('d', shm_array[4]) # Create new Value object
)
def move_niao(self, new_x, new_y):
with self.lock:
shm_array = np.ndarray((5,), dtype='d', buffer=self.niao_shm.buf)
shm_array[1] = new_x # Update position_x
shm_array[2] = new_y # Update position_y
def niao_worker(shared_world):
while True:
with shared_world.lock: # Lock access to shared data
shm_array = np.ndarray((5,), dtype='d', buffer=shared_world.niao_shm.buf)
print(f"Niao Worker accessing: Niao Position ({shm_array[1]}, {shm_array[2]})")
pos_x = shm_array[1]
pos_y = shm_array[2]
# Move Niao object
shared_world.move_niao(pos_x + 5.0, pos_y + 6.0)
start_time = time.time() # Record the start time
with shared_world.lock: # Lock access to shared data
shm_array = np.ndarray((5,), dtype='d', buffer=shared_world.niao_shm.buf)
end_time = time.time() # Record the end time
duration_microseconds = (end_time - start_time) * 1_000_000 # Convert to microseconds
print(f"Niao_worker access shm_array {duration_microseconds:.2f} microseconds.")
print(f"Niao Worker accessing post update: Niao Position ({shm_array[1]}, {shm_array[2]})")
time.sleep(1) # Delay for 1 second
def worker(shared_world):
while True:
niao = shared_world.get_niao()
print(f"Worker accessing: Position ({niao.position_x.value}, {niao.position_y.value})")
# Delay to reduce the loop's speed
time.sleep(1) # Delay for 1 second (adjust as needed)
def signal_handler(sig, frame):
print("Terminating processes...")
os._exit(0)
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler) # Handle Ctrl+C gracefully
shared_world = SharedWorld()
shared_world.create_niao_shared_memory()
# Add Niao object to the shared world
shared_world.add_niao(Niao(
Value('d', 0.0), # niao_axle_angle
Value('d', 0.0), # niao_position_x
Value('d', 0.0), # niao_position_y
Value('d', 0.0), # niao_energy
Value('d', 0.0) # niao_speed
))
# Create and start Niao process
niao_process = Process(target=niao_worker, args=(shared_world,))
niao_process.start()
# Create and start Worker process
worker_process = Process(target=worker, args=(shared_world,))
worker_process.start()
# Wait for processes to finish (they run indefinitely)
niao_process.join()
worker_process.join()
# Cleanup shared memory
shared_world.niao_shm.close()
shared_world.niao_shm.unlink()