multiprocessing.Process 处理“sys.exit”参数的方式与 Python 不同

multiprocessing.Process does not handle `sys.exit` arguments the same as Python

我正试图强迫 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

所以 multiprocessing 显然遵循 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

但这种行为差异的原因是什么(以及理由,如果适用)?

从技术上讲,我看到 here 导致此行为的行来自最初将 multiprocessing 引入标准库。我认为这种行为是不正确的,但想在创建问题之前了解为什么会这样。

有问题的代码来自原始 processing module which was integrated into Python 2.6/3.0 as part of PEP 371。原始存储库似乎丢失了时间,因此问题的 "why" 部分可能无法回答。

鉴于 multiprocessing 与 Python 行为不同时的类似问题(例如 here), it would likely be considered a bug, so I have filed it as bpo-35727.