bpo-30794: added kill() method to multiprocessing.Process (#2528)
* bpo-30794: added kill() method to multiprocessing.Process
* Added entries to documentation and NEWS
* Refactored test_terminate and test_kill
* Fix SIGTERM and SIGKILL being used on Windows for the tests
* Added "versionadded" marker to the documentation
* Fix trailing whitespace in doc
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index 5265639..9318a75 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -598,6 +598,12 @@
acquired a lock or semaphore etc. then terminating it is liable to
cause other processes to deadlock.
+ .. method:: kill()
+
+ Same as :meth:`terminate()` but using the ``SIGKILL`` signal on Unix.
+
+ .. versionadded:: 3.7
+
.. method:: close()
Close the :class:`Process` object, releasing all resources associated
diff --git a/Lib/multiprocessing/popen_fork.py b/Lib/multiprocessing/popen_fork.py
index 5af9d91..44ce9a9 100644
--- a/Lib/multiprocessing/popen_fork.py
+++ b/Lib/multiprocessing/popen_fork.py
@@ -49,16 +49,22 @@
return self.poll(os.WNOHANG if timeout == 0.0 else 0)
return self.returncode
- def terminate(self):
+ def _send_signal(self, sig):
if self.returncode is None:
try:
- os.kill(self.pid, signal.SIGTERM)
+ os.kill(self.pid, sig)
except ProcessLookupError:
pass
except OSError:
if self.wait(timeout=0.1) is None:
raise
+ def terminate(self):
+ self._send_signal(signal.SIGTERM)
+
+ def kill(self):
+ self._send_signal(signal.SIGKILL)
+
def _launch(self, process_obj):
code = 1
parent_r, child_w = os.pipe()
diff --git a/Lib/multiprocessing/popen_spawn_win32.py b/Lib/multiprocessing/popen_spawn_win32.py
index ecb86e9..3e42e9c 100644
--- a/Lib/multiprocessing/popen_spawn_win32.py
+++ b/Lib/multiprocessing/popen_spawn_win32.py
@@ -97,5 +97,7 @@
if self.wait(timeout=1.0) is None:
raise
+ kill = terminate
+
def close(self):
self.finalizer()
diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py
index fde97b7..ce4ce43 100644
--- a/Lib/multiprocessing/process.py
+++ b/Lib/multiprocessing/process.py
@@ -122,6 +122,13 @@
self._check_closed()
self._popen.terminate()
+ def kill(self):
+ '''
+ Terminate process; sends SIGKILL signal or uses TerminateProcess()
+ '''
+ self._check_closed()
+ self._popen.kill()
+
def join(self, timeout=None):
'''
Wait until child process terminates
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index d83b5a7..0515730 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -277,18 +277,18 @@
self.assertNotIn(p, self.active_children())
@classmethod
- def _test_terminate(cls):
+ def _sleep_some(cls):
time.sleep(100)
@classmethod
def _test_sleep(cls, delay):
time.sleep(delay)
- def test_terminate(self):
+ def _kill_process(self, meth):
if self.TYPE == 'threads':
self.skipTest('test not appropriate for {}'.format(self.TYPE))
- p = self.Process(target=self._test_terminate)
+ p = self.Process(target=self._sleep_some)
p.daemon = True
p.start()
@@ -309,7 +309,7 @@
# XXX maybe terminating too soon causes the problems on Gentoo...
time.sleep(1)
- p.terminate()
+ meth(p)
if hasattr(signal, 'alarm'):
# On the Gentoo buildbot waitpid() often seems to block forever.
@@ -333,9 +333,17 @@
p.join()
- # sometimes get p.exitcode == 0 on Windows ...
+ return p.exitcode
+
+ def test_terminate(self):
+ exitcode = self._kill_process(multiprocessing.Process.terminate)
if os.name != 'nt':
- self.assertEqual(p.exitcode, -signal.SIGTERM)
+ self.assertEqual(exitcode, -signal.SIGTERM)
+
+ def test_kill(self):
+ exitcode = self._kill_process(multiprocessing.Process.kill)
+ if os.name != 'nt':
+ self.assertEqual(exitcode, -signal.SIGKILL)
def test_cpu_count(self):
try:
@@ -462,7 +470,7 @@
for p in procs:
self.assertEqual(p.exitcode, 0)
- procs = [self.Process(target=self._test_terminate)
+ procs = [self.Process(target=self._sleep_some)
for i in range(N)]
for p in procs:
p.start()
diff --git a/Misc/NEWS.d/next/Library/2017-07-04-22-00-20.bpo-30794.qFwozm.rst b/Misc/NEWS.d/next/Library/2017-07-04-22-00-20.bpo-30794.qFwozm.rst
new file mode 100644
index 0000000..d960bd3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-07-04-22-00-20.bpo-30794.qFwozm.rst
@@ -0,0 +1,2 @@
+Added multiprocessing.Process.kill method to terminate using the SIGKILL
+signal on Unix.