import json import os import sys WORKER_PYTHON = "/home/tplohr/venvs/j1655/bin/python" WORKER_SCRIPT = "/home/tplohr/proj/SF25-26/xspec/heasoft-6.36/xscatXY/xspec_greg/numpy_worker.py" _worker_pid = None _worker_in = None _worker_out = None def _start_worker(): global _worker_pid, _worker_in, _worker_out if _worker_pid is not None: return # Parent writes to child stdin through p2c_w. p2c_r, p2c_w = os.pipe() # Parent reads child stdout through c2p_r. c2p_r, c2p_w = os.pipe() pid = os.fork() if pid == 0: # Child try: os.close(p2c_w) os.close(c2p_r) os.dup2(p2c_r, 0) os.dup2(c2p_w, 1) os.dup2(c2p_w, 2) os.close(p2c_r) os.close(c2p_w) os.execv(WORKER_PYTHON, [WORKER_PYTHON, WORKER_SCRIPT]) except Exception: os._exit(127) # Parent os.close(p2c_r) os.close(c2p_w) _worker_pid = pid _worker_in = os.fdopen(p2c_w, "w", buffering=1) _worker_out = os.fdopen(c2p_r, "r", buffering=1) def _stop_worker(): global _worker_pid, _worker_in, _worker_out if _worker_pid is None: return try: _worker_in.write(json.dumps({"cmd": "quit"}) + "\n") _worker_in.flush() except Exception: pass try: _worker_in.close() except Exception: pass try: _worker_out.close() except Exception: pass try: os.waitpid(_worker_pid, 0) except Exception: pass _worker_pid = None _worker_in = None _worker_out = None def calc_xscatxy(xext, yext, NH, Xpos): _start_worker() payload = { "cmd": "calc", # "Ex": Ex, "xext": xext, "yext": yext, "NH": NH, "Xpos": Xpos } # print("DEBUG: pyxscatxy.py is sending payload:", payload, file=sys.stderr) _worker_in.write(json.dumps(payload) + "\n") _worker_in.flush() line = _worker_out.readline() if not line: raise RuntimeError("xscatxy worker terminated unexpectedly") reply = json.loads(line) # print("DEBUG: reply from worker:", repr(reply)) if "error" in reply: raise RuntimeError(reply["error"]) return reply["result"]