首页 > 解决方案 > python 3.8 使用多处理和全局变量打破 python 3.5 代码

问题描述

我知道全局变量不好,但我很好奇是否有更多关于 macOS 10.15.6 上的 python 3.5 和 python 3.8 之间这种惊人差异的信息。

为什么在函数/进程中忽略块中全局client的分配?有没有办法编写它以便它在 python 版本中一致地工作?__main__foo()

更新:前两个 python 在我的 /usr/local/bin 中,所以它们一定来自 brew。

% python3.5 ./x.py
!!!Assigned client=repr({'hello': 1})
Using client=repr({'hello': 1})

% python3.8 ./x.py
!!!Assigned client=repr({'hello': 1})
Using client=repr(None)

如果我使用非 brew /usr/bin/python3 它是 3.7.3 并且可以按我的预期工作。

% /usr/bin/python3 --version
Python 3.7.3

% /usr/bin/python3 ./x.py
/usr/bin/python3 ./x.py
!!!Assigned client=repr({'hello': 1})
Using client=repr({'hello': 1})
from multiprocessing import Process

client = None

def foo():
    # Why is client None with python 3.8? It works with python 3.5.
    print("Using client=repr(%s)" % (repr(client)))

if __name__ == "__main__":
    client = {'hello':1}
    print("!!!Assigned client=repr(%s)" % (repr(client)))
    procs = []
    proc = Process(target=foo, args=())
    proc.start()
    proc.join()

奇怪,我的 python3.5 来自 2016 年,甚至似乎都不是来自 brew 所以不确定它来自哪里。顺便说一句,我不能brew uninstall python3,因为我有依赖它的包,比如awscliand s3cmd,不知道为什么他们不使用本机 macOS python3 (3.7)。

% ls -ltra /usr/local/bin/python*
lrwxr-xr-x  1 root     wheel  79 Nov 28  2016 /usr/local/bin/python3.5m-config -> ../../../Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5m-config
lrwxr-xr-x  1 root     wheel  72 Nov 28  2016 /usr/local/bin/python3.5m -> ../../../Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5m
lrwxr-xr-x  1 root     wheel  78 Nov 28  2016 /usr/local/bin/python3.5-config -> ../../../Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5-config
lrwxr-xr-x  1 root     wheel  74 Nov 28  2016 /usr/local/bin/python3.5-32 -> ../../../Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5-32
lrwxr-xr-x  1 root     wheel  71 Nov 28  2016 /usr/local/bin/python3.5 -> ../../../Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5
lrwxr-xr-x  1 root     wheel  72 Nov 28  2016 /usr/local/bin/python3-32 -> ../../../Library/Frameworks/Python.framework/Versions/3.5/bin/python3-32
lrwxr-xr-x  1 jamshid  staff  38 Jul 26 16:49 /usr/local/bin/python3 -> ../Cellar/python@3.8/3.8.5/bin/python3
lrwxr-xr-x  1 jamshid  staff  45 Jul 26 16:49 /usr/local/bin/python3-config -> ../Cellar/python@3.8/3.8.5/bin/python3-config
lrwxr-xr-x  1 jamshid  staff  40 Jul 26 16:49 /usr/local/bin/python3.8 -> ../Cellar/python@3.8/3.8.5/bin/python3.8
lrwxr-xr-x  1 jamshid  staff  47 Jul 26 16:49 /usr/local/bin/python3.8-config -> ../Cellar/python@3.8/3.8.5/bin/python3.8-config

我想答案是,正如 tim-peters 评论的那样,默认的进程创建者是 fork vs spawn (它创建一个没有设置全局的新进程)。是的,macOS 上的 python 3.8 更改了默认值: https ://docs.python.org/3/library/multiprocessing.html

在 3.8 版更改: 在 macOS 上,spawn start 方法现在是默认值。fork start 方法应该被认为是不安全的,因为它可能导致子进程崩溃。请参阅 bpo-33725。

标签: pythonpython-multiprocessing

解决方案


推荐阅读