如何在 Windows 上使用 Python for .NET 进行多处理?
How to do multiprocessing using Python for .NET on Windows?
现在我正在 Windows 上开发 C# 应用 运行。
一些进程是用 Python 编写的,通过 pythonnet 调用(Python for .NET)。
这些过程计算量大,所以我想并行进行。
它们是 CPU 有界的,可以独立处理。
据我所知,有两种可能的实现方式:
启动多个Python运行时
第一种方法是启动多个 Python 解释器,但似乎不可行。
因为pythonnet显然只能管理一个用静态方法初始化的解释器,PythonEngine.Initialize().
From the Python.NET documentation:
Important Note for embedders: Python is not free-threaded and uses a global interpreter lock to allow multi-threaded applications to interact safely with the Python interpreter. Much more information about this is available in the Python C-API documentation on the www.python.org Website.
When embedding Python in a managed application, you have to manage the GIL in just the same way you would when embedding Python in a C or C++ application.
Before interacting with any of the objects or APIs provided by the Python.Runtime namespace, calling code must have acquired the Python global interpreter lock by calling the PythonEngine.AcquireLock method. The only exception to this rule is the PythonEngine.Initialize method, which may be called at startup without having acquired the GIL.
在Python
中使用多处理包
另一种方法是使用多处理包。
根据 Python 文档,如果代码在 Windows 上运行以确保生成有限进程,则需要以下语句:
if __name__ == "__main__":
但是,在 Python 中编写的函数被视为模块的一部分,因为它嵌入到 .NET 中。
例如,以下代码是可执行的,但会无限生成进程。
//C#
static void Main(string[] args)
{
using (Py.GIL())
{
PythonEngine.Exec(
"print(__name__)\n" + //output is "buitlins"
"if __name__ == 'builtins':\n" +
" import test_package\n" + //import Python code below
" test_package.async_test()\n"
);
}
}
# Python
import concurrent.futures
def heavy_calc(x):
for i in range(int(1e7) * x):
i*2
def async_test():
# multiprocessing
with concurrent.futures.ProcessPoolExecutor(max_workers=8) as executor:
futures = [executor.submit(heavy_calc,x) for x in range(10)]
(done, notdone) = concurrent.futures.wait(futures)
for future in futures:
print(future.result())
有没有解决上述问题的好办法?
如有任何意见,我们将不胜感激。提前致谢。
对于每个 python 调用,
1.创建一个appDomain
2. 在 appdomain 中创建一个异步 运行 python 的任务。
由于它是独立的 AppDomain,因此静态方法将是独立的。
使用 AppDomain 创建一个应用程序很繁重,所以如果您的调用数量非常大,我无法做到这一点,但听起来您可能只有少量进程要 运行异步。
现在我正在 Windows 上开发 C# 应用 运行。 一些进程是用 Python 编写的,通过 pythonnet 调用(Python for .NET)。 这些过程计算量大,所以我想并行进行。
它们是 CPU 有界的,可以独立处理。
据我所知,有两种可能的实现方式:
启动多个Python运行时
第一种方法是启动多个 Python 解释器,但似乎不可行。 因为pythonnet显然只能管理一个用静态方法初始化的解释器,PythonEngine.Initialize().
From the Python.NET documentation:Important Note for embedders: Python is not free-threaded and uses a global interpreter lock to allow multi-threaded applications to interact safely with the Python interpreter. Much more information about this is available in the Python C-API documentation on the www.python.org Website.
When embedding Python in a managed application, you have to manage the GIL in just the same way you would when embedding Python in a C or C++ application.
Before interacting with any of the objects or APIs provided by the Python.Runtime namespace, calling code must have acquired the Python global interpreter lock by calling the PythonEngine.AcquireLock method. The only exception to this rule is the PythonEngine.Initialize method, which may be called at startup without having acquired the GIL.在Python
中使用多处理包 另一种方法是使用多处理包。 根据 Python 文档,如果代码在 Windows 上运行以确保生成有限进程,则需要以下语句:
if __name__ == "__main__":
但是,在 Python 中编写的函数被视为模块的一部分,因为它嵌入到 .NET 中。
例如,以下代码是可执行的,但会无限生成进程。
//C#
static void Main(string[] args)
{
using (Py.GIL())
{
PythonEngine.Exec(
"print(__name__)\n" + //output is "buitlins"
"if __name__ == 'builtins':\n" +
" import test_package\n" + //import Python code below
" test_package.async_test()\n"
);
}
}
# Python
import concurrent.futures
def heavy_calc(x):
for i in range(int(1e7) * x):
i*2
def async_test():
# multiprocessing
with concurrent.futures.ProcessPoolExecutor(max_workers=8) as executor:
futures = [executor.submit(heavy_calc,x) for x in range(10)]
(done, notdone) = concurrent.futures.wait(futures)
for future in futures:
print(future.result())
有没有解决上述问题的好办法? 如有任何意见,我们将不胜感激。提前致谢。
对于每个 python 调用, 1.创建一个appDomain 2. 在 appdomain 中创建一个异步 运行 python 的任务。
由于它是独立的 AppDomain,因此静态方法将是独立的。
使用 AppDomain 创建一个应用程序很繁重,所以如果您的调用数量非常大,我无法做到这一点,但听起来您可能只有少量进程要 运行异步。