bpo-35491: Enhance multiprocessing.BaseProcess.__repr__() (GH-11138)
* Add the pid and parent pid to multiprocessing.BaseProcess.__repr__(). * Add negative sign (ex: "-SIGTERM") to exitcode (process killed by a signal) * Only call _popen.poll() once. Example: <ForkProcess(ForkPoolWorker-1, started daemon)> becomes: <ForkProcess name='ForkPoolWorker-1' pid=12449 parent=12448 started daemon> Example: <ForkProcess(ForkPoolWorker-1, stopped[SIGTERM] daemon)> becomes: <ForkProcess name='ForkPoolWorker-1' pid=12960 parent=12959 stopped exitcode=-SIGTERM daemon>
This commit is contained in:
parent
cb0f5e29e3
commit
7acd50ad8b
|
@ -626,14 +626,14 @@ The :mod:`multiprocessing` package mostly replicates the API of the
|
||||||
>>> import multiprocessing, time, signal
|
>>> import multiprocessing, time, signal
|
||||||
>>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
|
>>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
|
||||||
>>> print(p, p.is_alive())
|
>>> print(p, p.is_alive())
|
||||||
<Process(..., initial)> False
|
<Process ... initial> False
|
||||||
>>> p.start()
|
>>> p.start()
|
||||||
>>> print(p, p.is_alive())
|
>>> print(p, p.is_alive())
|
||||||
<Process(..., started)> True
|
<Process ... started> True
|
||||||
>>> p.terminate()
|
>>> p.terminate()
|
||||||
>>> time.sleep(0.1)
|
>>> time.sleep(0.1)
|
||||||
>>> print(p, p.is_alive())
|
>>> print(p, p.is_alive())
|
||||||
<Process(..., stopped[SIGTERM])> False
|
<Process ... stopped exitcode=-SIGTERM> False
|
||||||
>>> p.exitcode == -signal.SIGTERM
|
>>> p.exitcode == -signal.SIGTERM
|
||||||
True
|
True
|
||||||
|
|
||||||
|
|
|
@ -248,6 +248,7 @@ class BaseProcess(object):
|
||||||
raise ValueError("process not started") from None
|
raise ValueError("process not started") from None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
exitcode = None
|
||||||
if self is _current_process:
|
if self is _current_process:
|
||||||
status = 'started'
|
status = 'started'
|
||||||
elif self._closed:
|
elif self._closed:
|
||||||
|
@ -257,19 +258,23 @@ class BaseProcess(object):
|
||||||
elif self._popen is None:
|
elif self._popen is None:
|
||||||
status = 'initial'
|
status = 'initial'
|
||||||
else:
|
else:
|
||||||
if self._popen.poll() is not None:
|
exitcode = self._popen.poll()
|
||||||
status = self.exitcode
|
if exitcode is not None:
|
||||||
|
status = 'stopped'
|
||||||
else:
|
else:
|
||||||
status = 'started'
|
status = 'started'
|
||||||
|
|
||||||
if type(status) is int:
|
info = [type(self).__name__, 'name=%r' % self._name]
|
||||||
if status == 0:
|
if self._popen is not None:
|
||||||
status = 'stopped'
|
info.append('pid=%s' % self._popen.pid)
|
||||||
else:
|
info.append('parent=%s' % self._parent_pid)
|
||||||
status = 'stopped[%s]' % _exitcode_to_name.get(status, status)
|
info.append(status)
|
||||||
|
if exitcode is not None:
|
||||||
return '<%s(%s, %s%s)>' % (type(self).__name__, self._name,
|
exitcode = _exitcode_to_name.get(exitcode, exitcode)
|
||||||
status, self.daemon and ' daemon' or '')
|
info.append('exitcode=%s' % exitcode)
|
||||||
|
if self.daemon:
|
||||||
|
info.append('daemon')
|
||||||
|
return '<%s>' % ' '.join(info)
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
||||||
|
@ -373,7 +378,7 @@ _exitcode_to_name = {}
|
||||||
|
|
||||||
for name, signum in list(signal.__dict__.items()):
|
for name, signum in list(signal.__dict__.items()):
|
||||||
if name[:3]=='SIG' and '_' not in name:
|
if name[:3]=='SIG' and '_' not in name:
|
||||||
_exitcode_to_name[-signum] = name
|
_exitcode_to_name[-signum] = f'-{name}'
|
||||||
|
|
||||||
# For debug and leak testing
|
# For debug and leak testing
|
||||||
_dangling = WeakSet()
|
_dangling = WeakSet()
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
:mod:`multiprocessing`: Add ``Pool.__repr__()`` and enhance
|
||||||
|
``BaseProcess.__repr__()`` (add pid and parent pid) to ease debugging. Pool
|
||||||
|
state constant values are now strings instead of integers, for example ``RUN``
|
||||||
|
value becomes ``'RUN'`` instead of ``0``.
|
Loading…
Reference in New Issue