| | import os |
| | import subprocess |
| | import sys |
| | import threading |
| |
|
| |
|
| | class ProcessMonitor: |
| | def __init__(self): |
| | self.process = None |
| | self.stdout = "" |
| | self.stderr = "" |
| | self.lock = threading.Lock() |
| |
|
| | def start_process(self, command): |
| | self.process = subprocess.Popen( |
| | command, |
| | stdout=subprocess.PIPE, |
| | stderr=subprocess.PIPE, |
| | bufsize=1, |
| | universal_newlines=True, |
| | ) |
| |
|
| | |
| | fd_out = self.process.stdout.fileno() |
| | fd_err = self.process.stderr.fileno() |
| |
|
| | if sys.platform != "win32": |
| | import fcntl |
| |
|
| | fl_out = fcntl.fcntl(fd_out, fcntl.F_GETFL) |
| | fl_err = fcntl.fcntl(fd_err, fcntl.F_GETFL) |
| | fcntl.fcntl(fd_out, fcntl.F_SETFL, fl_out | os.O_NONBLOCK) |
| | fcntl.fcntl(fd_err, fcntl.F_SETFL, fl_err | os.O_NONBLOCK) |
| |
|
| | |
| | threading.Thread(target=self._read_stdout).start() |
| | threading.Thread(target=self._read_stderr).start() |
| |
|
| | def _read_stdout(self): |
| | while self.process is not None and self.process.poll() is None: |
| | try: |
| | output = self.process.stdout.read() |
| | if output: |
| | with self.lock: |
| | self.stdout += output |
| | except: |
| | pass |
| |
|
| | def _read_stderr(self): |
| | while self.process is not None and self.process.poll() is None: |
| | try: |
| | error = self.process.stderr.read() |
| | if error: |
| | with self.lock: |
| | self.stderr += error |
| | except: |
| | pass |
| |
|
| | def get_output(self): |
| | with self.lock: |
| | return self.stdout, self.stderr |
| |
|
| | def stop_process(self): |
| | if self.process: |
| | self.process.terminate() |
| | self.process = None |
| |
|
| |
|
| | if __name__ == "__main__": |
| | import time |
| |
|
| | pm = ProcessMonitor() |
| | pm.start_process( |
| | [ |
| | "python", |
| | "-u", |
| | "-c", |
| | "import time; [print(i) or time.sleep(1) for i in range(5)]", |
| | ] |
| | ) |
| |
|
| | while pm.process and pm.process.poll() is None: |
| | stdout, stderr = pm.get_output() |
| | if stdout: |
| | print("STDOUT:", stdout) |
| | if stderr: |
| | print("STDERR:", stderr) |
| | time.sleep(1) |
| |
|
| | stdout, stderr = pm.get_output() |
| | print("Final STDOUT:", stdout) |
| | print("Final STDERR:", stderr) |
| |
|