现在我正在开发在Windows上运行的C#应用。一些过程用python编写,这些过程通过Pythonnet(.net的Python)命名。这些过程是重量计算的,所以我想并行进行。
它们是由CPU结合的,可以独立处理。
据我所知,有两种可能实现它的方法:
-
启动多个Python Runtime
第一种方法是推出多个Python口译员,但似乎不可行。因为pythonnet明显只能管理一个通过静态方法初始化的解释器,所以pythonengine.initialize()。
来自python.net文档:嵌入式的重要说明: python不是自由线程,并使用全局解释器锁定允许多线程应用程序与Python Instracters安全交互。有关此此信息的更多信息可在www.python.org网站上的Python C-API文档中获得。
将Python嵌入到托管应用程序中时,您必须以将Python嵌入C或C 应用程序时的方式管理GIL。
在与python.runtime名称空间提供的任何对象或API进行交互之前,调用代码必须通过调用PythonEngine.acquirelock方法来获取Python全局解释器锁定。此规则的唯一例外是pythonengine.Initialize方法,可以在启动时调用而无需获得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_packagen" + //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.创建一个应用程序 2.在AppDomain中创建一个将异步运行Python的任务。
由于它是单独的应用程序,因此静态方法将是独立的。
创建一个使用AppDomain很重,因此,如果您的电话数量极大,我无法做到,但听起来您可能只有少数流程可以异步运行。