【问题标题】:Pyinstaller not allowing multiprocessing with MacOSPyinstaller 不允许使用 MacOS 进行多处理
【发布时间】:2022-01-28 00:28:10
【问题描述】:

我有一个 python 文件,我想打包为 MacOS 11.6 的可执行文件。

python 文件(称为 Service.py)依赖于另一个 json 文件,并且在使用 python 运行时运行良好。我的文件使用 argparse,因为参数可能因需要而异。

如何用python调用文件的例子:

python3 Service.py -v Zephyr_Scale_Cloud https://myurl.cloud/ philippa@email.com password1 group3

当文件是可执行文件时,它的运行方式完全相同:

./Service.py -v Zephyr_Scale_Cloud https://myurl.cloud/ philippa@email.com password1 group3

我可以使用 PyInstaller 打包文件并运行可执行文件。

用于打包文件的命令:

pyinstaller --paths=/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/ Service.py

但是,当我到达需要多处理的地步时,参数就会丢失。我的第二个参数(这里记为 https://myurl.cloud)是我需要的 URL。

我看到的错误是:

[MAIN] Starting new process RUNID9157
url before constructing the client recognised as pipe_handle=15
usage: Service [-h] test_management_tool url
Service: error: the following arguments are required: url
Traceback (most recent call last):
  File "urllib3/connection.py", line 174, in _new_conn
  File "urllib3/util/connection.py", line 72, in create_connection
  File "socket.py", line 954, in getaddrinfo

我已经完成了一些日志记录,并且确实可以正确读取 url。但是一旦进程启动并获取它需要的内容,url 就会更改为“pipe_handle=x”,在上面的代码中它是 pipe_handle=15。 我需要 url 来检索身份验证令牌,但它只是停止被读取为正确的值并更改为此 pipe_handle 值。我不知道为什么。

还有其他人看过吗?!

我正在使用 Python 3.9、PyInstaller 4.4 和 ArgParse。 我也加了

if __name__ == "__main__":
    if sys.platform.startswith('win'):
        # On Windows - multiprocessing is different to Unix and Mac.
        multiprocessing.freeze_support() 

到我的 if name = "main" 部分,因为我在其他帖子上看到了这个,但它没有帮助。

有人可以帮忙吗?

【问题讨论】:

    标签: python multithreading multiprocessing pyinstaller argparse


    【解决方案1】:

    通过sys.argv 发送命令很复杂,因为多处理的“spawn”启动方法使用它为父子之间的初始通信管道传递文件描述符。

    我在这里稍微投射一下,因为您没有分享如何/在何处调用 argparse 以及如何/在何处调用多处理的代码

    如果您在 if __name__ == "__main__": 之外解析 args,则 args 可能会在子代中的 sys.argvmultiprocessing.spawn.prepare() 自动清理之前被解析(在子代 import __main__ 上重新解析)。您应该能够通过在目标函数中移动 argparse 内容来解决此问题。在父函数中解析 args 也可能更容易,并且只需将解析结果作为参数发送给目标函数。有关sys.argvmultiprocessing 的进一步讨论,请参阅我的this 答案。

    【讨论】:

    • tl;dr 使用 Process(target=foo, **args=(my, args)**) 而不是 sys.argv 将参数发送到子函数
    猜你喜欢
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多