def main(): # Set up shared data shm = SharedMemory(IPC_PRIVATE, size=SHARED_MEMORY_SIZE, flags=IPC_CREAT) mutex = Semaphore(IPC_PRIVATE, initial_value=1, flags=IPC_CREAT | IPC_EXCL) empty = Semaphore(IPC_PRIVATE, initial_value=BUF_SIZE, flags=IPC_CREAT | IPC_EXCL) full = Semaphore(IPC_PRIVATE, flags=IPC_CREAT | IPC_EXCL) print('Forking producer') producer_id = fork() if not producer_id: producer(shm, mutex, empty, full) print('Forking consumer') consumer_id = fork() if not consumer_id: consumer(shm, mutex, empty, full) # Wait for children wait() wait() # Clean up. shm.detach() shm.remove() mutex.remove() empty.remove() full.remove()
class FrameBufferClient: def __init__(self, key: str): self.buffer = None self.key = key self.shared_memory = None self.size = None self._hasher = pyhash.t1ha0() def __enter__(self): self.start() return self def __exit__(self, exc_type, exc_value, exc_traceback): self.stop() def start(self): """ Start shared memory client """ self.shared_memory = SharedMemory(key=self.key) self.buffer = memoryview(self.shared_memory) self.size = self.shared_memory.size logger.info('Started FrameBufferClient - key=%s, size=%d', \ self.key, self.size) def stop(self): """ Stop shared memory client """ self.shared_memory.detach() logger.info('Stopped FrameBufferClient - key=%s, size=%d', \ self.key, self.size) def set_key(self, key): """ Set shared memory key (must be done before __enter__/start) """ self.key = key def write(self, offset: int, data: bytes) -> str: """ Returns `checksum` """ bytes_to_back = min(len(data), self.size - offset) bytes_to_front = len(data) - bytes_to_back self.buffer[offset:offset + bytes_to_back] = data[0:bytes_to_back] if bytes_to_front > 0: self.buffer[0:bytes_to_front] = data[bytes_to_back:] _hash = base64.b64encode( self._hasher(data).to_bytes(8, sys.byteorder)).decode() return _hash def read(self, offset: int, size: int, checksum: str) -> bytes: """ Raises `FrameBufferTimeout` on invalid checksum """ bytes_from_back = min(size, self.size - offset) bytes_from_front = size - bytes_from_back data = bytes(self.buffer[offset:offset + bytes_from_back]) if bytes_from_front > 0: data += bytes(self.buffer[0:bytes_from_front]) _hash = base64.b64encode( self._hasher(data).to_bytes(8, sys.byteorder)).decode() if _hash != checksum: raise FrameBufferTimeout( "Invalid checksum - buffer already reused") return data
class FrameBufferServer: def __init__(self, size: int): self.buffer = None self.key = None self.shared_memory = None self.size = size self.offset = 0 def __enter__(self): self.start() return self def __exit__(self, exc_type, exc_value, exc_traceback): self.stop() def start(self): """ Start shared memory server """ self.shared_memory = SharedMemory(key=None, flags=IPC_CREX, size=self.size) self.buffer = memoryview(self.shared_memory) self.key = self.shared_memory.key logger.info('Started FrameBufferServer - key=%s, size=%d', self.key, self.size) def stop(self): """ Stop shared memory server """ self.shared_memory.detach() self.shared_memory.remove() logger.info('Stopped FrameBufferServer - key=%s, size=%d', self.key, self.size) def get_key(self) -> str: """ Return client key for shared memory access """ return self.key def allocate(self, size: int) -> int: """ Allocates a chunk of data and returns offset """ offset = self.offset self.offset = (self.offset + size) % self.size return offset
#!usr/bin/env python # encoding: utf-8 # Archivo de lectura de la memoria compartida. from sysv_ipc import SharedMemory from numpy import frombuffer, float32 from subprocess import call shm_key = 0x1234; # Vinvculamos la memoria compartida a una instancia. mem = SharedMemory(shm_key) # Leemos la memoria compartida. memory_value = mem.read() # Convertimos la lectura de bytes a numpy array. y = frombuffer(memory_value, dtype=float32) print(y) # Desvinculamos la instancia. mem.detach() # Removemos la memoria. mem.remove()