如何在Windows上使用Python for .NET进行多处理?

sfb*_*sfb 12 c# python windows multiprocessing python.net

现在我正在开发在Windows上运行的C#app.一些进程是用Python编写的,通过pythonnet(Python for .NET)调用.这些过程计算量很大,所以我想并行完成.

它们是CPU限制的,可以独立处理.

据我所知,有两种可能的方法来实现它:

  1. 启动多个Python运行时
    第一种方法是启动多个Python解释器,但似乎不可行.因为pythonnet通常只能管理一个由静态方法初始化的解释器,PythonEngine.Initialize().
    从Python.NET文档:

    嵌入器的重要说明: Python不是自由线程的,它使用全局解释器锁来允许多线程应用程序与Python解释器安全地交互.有关此内容的更多信息,请参见www.python.org网站上的Python C-API文档.
    在托管应用程序中嵌入Python时,您必须像在C或C++应用程序中嵌入Python一样管理GIL.
    在与Python.Runtime命名空间提供的任何对象或API交互之前,调用代码必须通过调用PythonEngine.AcquireLock方法获取Python全局解释器锁.此规则的唯一例外是PythonEngine.Initialize方法,可以在启动时调用,而无需获取GIL.

  2. 在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"
                );
        }
    }
Run Code Online (Sandbox Code Playgroud)
# 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())
Run Code Online (Sandbox Code Playgroud)

解决上述问题有什么好主意吗?任何意见将不胜感激.提前致谢.

Ctz*_*525 3

对于每个 python 调用, 1. 创建一个 appDomain 2. 在 appdomain 中创建一个将异步运行 python 的任务。

由于它是单独的 AppDomain,因此静态方法将是独立的。

使用 AppDomain 创建一个任务很繁重,所以如果您的调用数量非常大,我就无法做到这一点,但听起来您可能只有少量进程需要异步运行。