Python多进程冻结fork炸弹

3

我有一个简单易懂的 Python 脚本:

import multiprocessing


def foo():
    print('running foo')


def main():
    print('start')
    ctx = multiprocessing.get_context('spawn')

    p = ctx.Process(target=foo)
    p.start()
    p.join()


if __name__ == '__main__':
    main()

当使用Python解释器调用时,它会按照预期运行:

$ python test.py
start
running foo

尝试冻结脚本的操作并不好。相比之下,两者都需要使用HTML标签。
pyinstaller test.py

并且

cxfreeze test.py

导致实际上是一个分叉炸弹:

$ ./dist/test/test
start
start
start
start
.
.
.

观察htop,我们会发现确实有很多进程被生成,导致机器很快就会锁定。

将启动方法从spawn改为fork,不会导致分叉炸弹。

ctx = multiprocessing.get_context('fork')

冻结过程中与fork相容而不是spawn的原因是什么?冻结过程是否可以更改以允许spawn?

我猜你正在运行Linux,对吗? - Jean-François Fabre
在 Windows 上冻结可执行文件时需要调用 freeze_support()。不过在 Linux 上似乎没什么用。 - Jean-François Fabre
是的,使用Linux。为了完整起见,我还尝试了freeze_support(),但没有改变。 - Sam
正常情况下,仅在 Windows 系统中需要使用 freeze_support。在 multiprocessing 模块中,Windows 和 Linux 之间存在轻微差异。Linux 的默认值为“fork”,而 Windows 的默认值为“spawn”。这似乎与您的问题有关。 - Jean-François Fabre
我很难找到一个好的描述forkspawn之间的区别,除了文档中概述的传递给新进程的资源方面的差异。 - Sam
在非 Windows 系统上的 spawn 支持中似乎存在一个 bug。 - torek
1个回答

0

我成功地通过cpython repo中的Tools/freeze/freeze.py脚本复现了问题,因此问题确实比cx_freeze或pyinstaller更深入。

经过进一步的挖掘,我发现我不是唯一遇到这个问题的人-在我遇到问题的一个月前,以下问题已经被提出:

https://bugs.python.org/issue32146

他们有一些修复的想法,希望能够在3.7.x版本中实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接