Attempts to terminate or kill the executor's workers based off the given operation. Iterates through all of the current processes and performs the relevant task if the process is still alive. After terminating workers, the pool will be in a broken state and no longer
(self, operation)
| 890 | shutdown.__doc__ = _base.Executor.shutdown.__doc__ |
| 891 | |
| 892 | def _force_shutdown(self, operation): |
| 893 | """Attempts to terminate or kill the executor's workers based off the |
| 894 | given operation. Iterates through all of the current processes and |
| 895 | performs the relevant task if the process is still alive. |
| 896 | |
| 897 | After terminating workers, the pool will be in a broken state |
| 898 | and no longer usable (for instance, new tasks should not be |
| 899 | submitted). |
| 900 | """ |
| 901 | if operation not in _SHUTDOWN_CALLBACK_OPERATION: |
| 902 | raise ValueError(f"Unsupported operation: {operation!r}") |
| 903 | |
| 904 | processes = {} |
| 905 | if self._processes: |
| 906 | processes = self._processes.copy() |
| 907 | |
| 908 | # shutdown will invalidate ._processes, so we copy it right before |
| 909 | # calling. If we waited here, we would deadlock if a process decides not |
| 910 | # to exit. |
| 911 | self.shutdown(wait=False, cancel_futures=True) |
| 912 | |
| 913 | if not processes: |
| 914 | return |
| 915 | |
| 916 | for proc in processes.values(): |
| 917 | try: |
| 918 | if not proc.is_alive(): |
| 919 | continue |
| 920 | except ValueError: |
| 921 | # The process is already exited/closed out. |
| 922 | continue |
| 923 | |
| 924 | try: |
| 925 | if operation == _TERMINATE: |
| 926 | proc.terminate() |
| 927 | elif operation == _KILL: |
| 928 | proc.kill() |
| 929 | except ProcessLookupError: |
| 930 | # The process just ended before our signal |
| 931 | continue |
| 932 | |
| 933 | def terminate_workers(self): |
| 934 | """Attempts to terminate the executor's workers. |