>>> import multiprocessing, time, signal
>>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
>>> print(p, p.is_alive())
- <Process(..., initial)> False
+ <Process ... initial> False
>>> p.start()
>>> print(p, p.is_alive())
- <Process(..., started)> True
+ <Process ... started> True
>>> p.terminate()
>>> time.sleep(0.1)
>>> print(p, p.is_alive())
- <Process(..., stopped[SIGTERM])> False
+ <Process ... stopped exitcode=-SIGTERM> False
>>> p.exitcode == -signal.SIGTERM
True
raise ValueError("process not started") from None
def __repr__(self):
+ exitcode = None
if self is _current_process:
status = 'started'
elif self._closed:
elif self._popen is None:
status = 'initial'
else:
- if self._popen.poll() is not None:
- status = self.exitcode
- else:
- status = 'started'
-
- if type(status) is int:
- if status == 0:
+ exitcode = self._popen.poll()
+ if exitcode is not None:
status = 'stopped'
else:
- status = 'stopped[%s]' % _exitcode_to_name.get(status, status)
+ status = 'started'
- return '<%s(%s, %s%s)>' % (type(self).__name__, self._name,
- status, self.daemon and ' daemon' or '')
+ info = [type(self).__name__, 'name=%r' % self._name]
+ if self._popen is not None:
+ info.append('pid=%s' % self._popen.pid)
+ info.append('parent=%s' % self._parent_pid)
+ info.append(status)
+ if exitcode is not None:
+ exitcode = _exitcode_to_name.get(exitcode, exitcode)
+ info.append('exitcode=%s' % exitcode)
+ if self.daemon:
+ info.append('daemon')
+ return '<%s>' % ' '.join(info)
##
for name, signum in list(signal.__dict__.items()):
if name[:3]=='SIG' and '_' not in name:
- _exitcode_to_name[-signum] = name
+ _exitcode_to_name[-signum] = f'-{name}'
# For debug and leak testing
_dangling = WeakSet()
--- /dev/null
+: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``.