Extension of Process that Keeps track of the child process' result. This class is useful for executing a function in a child process and storing the result (i.e., the return value and exception raised). Inspired by: https://stackoverflow.com/a/33599967/3769045
| 14 | |
| 15 | |
| 16 | class ProcessWithResult(multiprocessing.Process): |
| 17 | """Extension of Process that Keeps track of the child process' result. |
| 18 | |
| 19 | This class is useful for executing a function in a child process and storing |
| 20 | the result (i.e., the return value and exception raised). |
| 21 | |
| 22 | Inspired by: |
| 23 | https://stackoverflow.com/a/33599967/3769045 |
| 24 | """ |
| 25 | |
| 26 | def __init__(self, *args, **kwargs): |
| 27 | super().__init__(*args, **kwargs) |
| 28 | # Create the Connection objects used for communication between the |
| 29 | # parent and child processes. |
| 30 | self.parent_conn, self.child_conn = multiprocessing.Pipe() |
| 31 | |
| 32 | def run(self): |
| 33 | """Method to be run in sub-process.""" |
| 34 | result = ProcessResult() |
| 35 | try: |
| 36 | if self._target: |
| 37 | result.return_value = self._target(*self._args, **self._kwargs) |
| 38 | except Exception as e: |
| 39 | result.exception = e |
| 40 | raise |
| 41 | finally: |
| 42 | self.child_conn.send(result) |
| 43 | |
| 44 | def result(self): |
| 45 | """Get the result from the child process. |
| 46 | |
| 47 | Returns: |
| 48 | If the child process has completed, a ProcessResult object. |
| 49 | Otherwise, a None object. |
| 50 | """ |
| 51 | return self.parent_conn.recv() if self.parent_conn.poll() else None |
| 52 | |
| 53 | |
| 54 | def with_timeout(function, *, args=None, timeout_in_seconds): |