Skip to content

Commit ecb035c

Browse files
authored
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.
1 parent 5a88d50 commit ecb035c

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

Lib/test/libregrtest/runtest_mp.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import json
44
import os
55
import queue
6+
import signal
67
import subprocess
78
import sys
89
import threading
@@ -31,6 +32,8 @@
3132
# Time to wait until a worker completes: should be immediate
3233
JOIN_TIMEOUT = 30.0 # seconds
3334

35+
USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
36+
3437

3538
def must_stop(result, ns):
3639
if result.result == INTERRUPTED:
@@ -59,12 +62,16 @@ def run_test_in_subprocess(testname, ns):
5962
# Running the child from the same working directory as regrtest's original
6063
# invocation ensures that TEMPDIR for the child is the same when
6164
# sysconfig.is_python_build() is true. See issue 15300.
65+
kw = {}
66+
if USE_PROCESS_GROUP:
67+
kw['start_new_session'] = True
6268
return subprocess.Popen(cmd,
6369
stdout=subprocess.PIPE,
6470
stderr=subprocess.PIPE,
6571
universal_newlines=True,
6672
close_fds=(os.name != 'nt'),
67-
cwd=support.SAVEDCWD)
73+
cwd=support.SAVEDCWD,
74+
**kw)
6875

6976

7077
def run_tests_worker(ns, test_name):
@@ -149,16 +156,24 @@ def _kill(self):
149156
return
150157
self._killed = True
151158

152-
print(f"Kill {self}", file=sys.stderr, flush=True)
159+
if USE_PROCESS_GROUP:
160+
what = f"{self} process group"
161+
else:
162+
what = f"{self}"
163+
164+
print(f"Kill {what}", file=sys.stderr, flush=True)
153165
try:
154-
popen.kill()
166+
if USE_PROCESS_GROUP:
167+
os.killpg(popen.pid, signal.SIGKILL)
168+
else:
169+
popen.kill()
155170
except ProcessLookupError:
156-
# Process completed, the TestWorkerProcess thread read its exit
157-
# status, but Popen.send_signal() read the returncode just before
158-
# Popen.wait() set returncode.
171+
# popen.kill(): the process completed, the TestWorkerProcess thread
172+
# read its exit status, but Popen.send_signal() read the returncode
173+
# just before Popen.wait() set returncode.
159174
pass
160175
except OSError as exc:
161-
print_warning(f"Failed to kill {self}: {exc!r}")
176+
print_warning(f"Failed to kill {what}: {exc!r}")
162177

163178
def stop(self):
164179
# Method called from a different thread to stop this thread
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
test.regrtest now uses process groups in the multiprocessing mode (-jN command
2+
line option) if process groups are available: if :func:`os.setsid` and
3+
:func:`os.killpg` functions are available.

0 commit comments

Comments
 (0)