class Viewer: def __init__(self): # create a pipe to communicate with the child (self.pipe, self.child_pipe) = Pipe() # create the subprocess self.child = Process(target=self._handler) # set the child to run as a background process (i.e., exit when parent does) self.child.daemon = True self.child.start() def update(self, knowledge_base, robot_state): self.pipe.send((knowledge_base, robot_state)) # path = '/tmp/transfer.pickle' # pickle.dump((knowledge_base, robot_state), open(path, 'wb')) # self.pipe.send(path) def close(self): # signal the child to close self.pipe.close() # wait a bit for the process to exit self.child.wait(1) # kill the process if it doesn't exit normally if self.child.is_alive(): logger.warn("Viewer escalating to kill child") self.child.cancel() self.child = None logger.info("Viewer closed") def _handler(self): logger.debug("child {} start".format(self.child.pid)) viewer = RemoteKnowledgeBaseViewer(self.child_pipe) viewer.run() @property def heartbeat(self): logger.info("checking for heartbeat") if self.pipe.poll(): logger.info("heartbeat present") self.pipe.recv() logger.info("heartbeat read") return True else: return False
async def kill_sub_pool(self, process: multiprocessing.Process, force: bool = False): process.cancel()