现在我正在开发C#应用程序,在Windows上运行。 其中一些进程是用Python编写的,并通过pythonnet(Python for .NET)调用。 这些进程需要大量计算,所以我想并行执行它们。
它们是CPU密集型的,可以独立处理。
据我所知,有两种可能的实现方式:
启动多个Python运行时
第一种方法是启动多个Python解释器,但似乎不可行。 因为pythonnet显然只能管理一个由静态方法PythonEngine.Initialize()初始化的解释器。
来自Python.NET文档:嵌入者的重要提示: Python不是自由线程的,并使用全局解释器锁定来允许多线程应用程序安全地与Python解释器交互。有关此更多信息,请参见www.python.org网站上的Python C-API文档。
在将Python嵌入托管应用程序中时,必须像在将Python嵌入C或C ++应用程序中时那样管理GIL。
在调用Python.Runtime命名空间提供的任何对象或API之前,调用代码必须通过调用PythonEngine.AcquireLock方法获取Python全局解释器锁(GIL)。唯一的例外是PythonEngine.Initialize方法,该方法可以在启动时调用而无需获取GIL。在Python中使用multiprocessing包
另一种方法是使用multiprocessing包。 根据Python文档,在Windows上运行代码时,以下语句对于确保生成有限进程是必要的:
if __name__ == "__main__":
但是,由于它被嵌入到.NET中,所以用Python编写的函数被视为模块的一部分。 例如,下面的代码可执行,但会无限生成进程。
//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())
有没有解决以上问题的好主意?任何评论将不胜感激。提前致谢。