diff options
author | Victor Stinner <vstinner@python.org> | 2019-10-18 13:49:08 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-18 13:49:08 (GMT) |
commit | ecb035cd14c11521276343397151929a94018a22 (patch) | |
tree | 34bb11f5c1a5f79996b66bba66472c73188a6959 | |
parent | 5a88d50ff013a64fbdb25b877c87644a9034c969 (diff) | |
download | cpython-ecb035cd14c11521276343397151929a94018a22.zip cpython-ecb035cd14c11521276343397151929a94018a22.tar.gz cpython-ecb035cd14c11521276343397151929a94018a22.tar.bz2 |
bpo-38502: regrtest uses process groups if available (GH-16829)
test.regrtest now uses process groups in the multiprocessing mode
(-jN command line option) if process groups are available: if
os.setsid() and os.killpg() functions are available.
-rw-r--r-- | Lib/test/libregrtest/runtest_mp.py | 29 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst | 3 |
2 files changed, 25 insertions, 7 deletions
diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index 8026de1..fc12ea7 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -3,6 +3,7 @@ import faulthandler import json import os import queue +import signal import subprocess import sys import threading @@ -31,6 +32,8 @@ assert MAIN_PROCESS_TIMEOUT >= PROGRESS_UPDATE # Time to wait until a worker completes: should be immediate JOIN_TIMEOUT = 30.0 # seconds +USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg")) + def must_stop(result, ns): if result.result == INTERRUPTED: @@ -59,12 +62,16 @@ def run_test_in_subprocess(testname, ns): # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. + kw = {} + if USE_PROCESS_GROUP: + kw['start_new_session'] = True return subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, close_fds=(os.name != 'nt'), - cwd=support.SAVEDCWD) + cwd=support.SAVEDCWD, + **kw) def run_tests_worker(ns, test_name): @@ -149,16 +156,24 @@ class TestWorkerProcess(threading.Thread): return self._killed = True - print(f"Kill {self}", file=sys.stderr, flush=True) + if USE_PROCESS_GROUP: + what = f"{self} process group" + else: + what = f"{self}" + + print(f"Kill {what}", file=sys.stderr, flush=True) try: - popen.kill() + if USE_PROCESS_GROUP: + os.killpg(popen.pid, signal.SIGKILL) + else: + popen.kill() except ProcessLookupError: - # Process completed, the TestWorkerProcess thread read its exit - # status, but Popen.send_signal() read the returncode just before - # Popen.wait() set returncode. + # popen.kill(): the process completed, the TestWorkerProcess thread + # read its exit status, but Popen.send_signal() read the returncode + # just before Popen.wait() set returncode. pass except OSError as exc: - print_warning(f"Failed to kill {self}: {exc!r}") + print_warning(f"Failed to kill {what}: {exc!r}") def stop(self): # Method called from a different thread to stop this thread diff --git a/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst b/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst new file mode 100644 index 0000000..1df523e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst @@ -0,0 +1,3 @@ +test.regrtest now uses process groups in the multiprocessing mode (-jN command +line option) if process groups are available: if :func:`os.setsid` and +:func:`os.killpg` functions are available. |