嵌入式python:多处理不起作用

2022-01-12 00:00:00 python multiprocessing

问题描述

我正在使用作为脚本环境嵌入到应用程序 (x64) 中的 Python 3.1.4.到目前为止,我在使用嵌入式 python 时遇到了很多限制.不知道是不是正常,还是应用程序的程序员屏蔽了一些功能.

I'm using Python 3.1.4 that is embedded as a scripting environment in an application(x64). So far I have encountered a lot of limitations with the embedded python. I don't know if it is normal or if the programmers of the application have blocked some functionalities.

例如以下代码不起作用:

For example the following code isn't working:

from multiprocessing import Process
def f(name):
    print('hello', name)

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

# --> error in forking.py: 'module' object has no attribute 'argv'
# print(sys.argv) gives the same error

sys.executable 返回应用程序的路径.

sys.executable return the path to the application.

我也试过了:

multiprocessing.forking.set_executable('C:Python31python.exe')
multiprocessing.set_executable('C:Python31python.exe')

没有成功.

是否有可能的解决方法?我不太可能有能力让应用程序的开发人员更改他们的代码中的某些内容.

Is there a workaround possible ? It is very unlikely that I would have the leverage to make the developers of the application change something in their code.

谢谢

编辑

我通过添加以下内容使其工作:

I got it to work by adding the following:

sys.argv = ['c:/pathToScript/scipt.py']

我也需要这条线:

multiprocessing.set_executable('C:/Python31/python.exe')

否则会打开另一个应用程序实例而不是运行代码.

Otherwise an other instance of the application open instead of running the code.

我剩下的唯一问题是我不能使用控制应用程序本身的方法(例如:create_project()、add_report()、..).我的主要目标是能够调用多个方法而无需等待第一个方法完成.但我认为这是不可能的.

The only problem I have left is that I can't use the methods that control the application itself (like: create_project(), add_report(),..). My primary goal was to be able to call multiple methods without the need to wait for the first one to finish completion. But I think this is just not possible.


解决方案

默认情况下,sys.argv 在嵌入代码中不可用:

By default, sys.argv is not available in embedded code:

基本的初始化函数是 Py_Initialize().这初始化加载模块的表,并创建基本模块内置函数、__main__ 和 sys.它还初始化模块搜索路径(sys.path).

Embedding Python

The basic initialization function is Py_Initialize(). This initializes the table of loaded modules, and creates the fundamental modules builtins, __main__, and sys. It also initializes the module search path (sys.path).

Py_Initialize() 没有设置脚本参数列表"(sys.argv).如果稍后将执行的 Python 代码需要此变量,它必须通过调用 PySys_SetArgvEx(argc, argv,updatepath) 在调用 Py_Initialize() 之后

Py_Initialize() does not set the "script argument list" (sys.argv). If this variable is needed by Python code that will be executed later, it must be set explicitly with a call to PySys_SetArgvEx(argc, argv, updatepath) after the call to Py_Initialize()

在 Windows 上,multiprocessing 必须从头开始生成新进程.它使用命令行开关--multiprocessing-fork 来区分子进程,并将原始的argv从父进程传递给子进程.

On Windows, multiprocessing must spawn new processes from scratch. It uses a command line switch --multiprocessing-fork to distinguish child processes, and also transmits the original argv from parent to child.

在创建子进程之前分配 sys.argv = ['c:/pathToScript/scipt.py'],就像您发现的那样,似乎是一个很好的解决方法.

Assigning sys.argv = ['c:/pathToScript/scipt.py'] before creating subprocesses, like you discovered, would seem to be a good workaround.

第二个相关的文档是 multiprocessing.set_executable():

A second relevant piece of documentation is that of multiprocessing.set_executable():

设置 Python 的路径启动子进程时使用的解释器.(默认情况下sys.executable 被使用).嵌入者可能需要做一些事情喜欢

Sets the path of the Python interpreter to use when starting a child process. (By default sys.executable is used). Embedders will probably need to do some thing like

set_executable(os.path.join(sys.exec_prefix, 'pythonw.exe'))
之前他们可以创建子进程.(仅限 Windows)

set_executable(os.path.join(sys.exec_prefix, 'pythonw.exe'))
before they can create child processes. (Windows only)

相关文章