multiprocessing.Process не обрабатывает аргументы `sys.exit` так же, как Python - PullRequest
0 голосов
/ 12 января 2019

Я пытаюсь multiprocessing.Process дать мне тот же код завершения, что и интерпретатор Python, но он ведет себя по-разному в зависимости от того, как я вызываю sys.exit. Например:

from multiprocessing import Process
import sys


def run(fn):
    p = Process(target=fn)
    p.start()
    p.join()
    return p.exitcode


print(run(lambda: sys.exit(2)))
print(run(lambda: sys.exit(None)))
print(run(lambda: sys.exit()))

при исполнении дает:

$ python exit.py
2
1
1

но когда я запускаю Python напрямую, я вижу разные результаты:

$ for arg in 2 None ''; do python -c "import sys; sys.exit($arg)"; echo $?; done
2
0
0

Таким образом, многопроцессорная обработка явно учитывает sys.exit (поскольку sys.exit(2) работает), но ведет себя по-разному с sys.exit() и sys.exit(None).

Я могу обойти это достаточно легко, обернув целевую функцию, например

try:
    target()
except SystemExit as e:
    if not e.args:
        e.args = (0,)
        e.code = 0
    raise

но какова причина (и обоснование, если применимо) такой разницы в поведении?

Технически, я вижу здесь , что строка, вызывающая такое поведение, происходит от первоначального введения многопроцессорности в стандартную библиотеку. Я думаю, что это неправильное поведение, но я хочу понять, почему это так, прежде чем создавать проблему.

1 Ответ

0 голосов
/ 12 января 2019

Данный код взят из исходного обрабатывающего модуля, который был интегрирован в Python 2.6 / 3.0 как часть PEP 371 . Исходный репозиторий кажется потерянным во времени, поэтому часть вопроса «почему» может не отвечать.

Учитывая схожие проблемы с multiprocessing, когда он отличается от поведения Python (например, здесь ), это, вероятно, будет считаться ошибкой, поэтому я подал его как bpo-35727 .

...