在多线程c#应用程序中嵌入Python

时间:2013-12-25 15:00:52

标签: c# python multithreading python-embedding python.net

我的应用程序提供了python插件系统。为了从c#调用python。我编写了一个嵌入python dll的C包装器。你可以在这里找到要点 C wrapper gist

然后我在C#中使用P / Invoke来调用C dll。像这样:

[DllImport("PyWinAlfred.dll")]
private extern static IntPtr ExecPython(string directory, string file, string query);

如果我没有在C#创建的多个线程中执行上面的代码,那就没关系。问题是如果我没有使用线程,c#中的主线程将被阻塞,而python代码需要很长时间才能执行。
这是我使用的C#多线程代码:

ThreadPool.QueueUserWorkItem(state =>
{
   ExecPython(directory,file,query);
});

所以,我尝试在C包装器代码中添加多个线程支持。正如你在那个要点中看到的那样。我试着添加:

// Create GIL/enable threads
PyEval_InitThreads();
PyGILState_STATE gstate = PyGILState_Ensure();

//python codes

PyGILState_Release(gstate);

但这对我不起作用。当我创建一些线程来调用那个dll时,我会得到一个异常。

我也试过以下代码。仍然没有奏效。

PyThreadState* state = PyThreadState_Get();
// Once in each thread
PyThreadState* stateForNewThread = PyThreadState_New(state->interp);
PyEval_RestoreThread(stateForNewThread);

//python codes

PyEval_SaveThread();

我想知道这是否是因为我在每次调用中都放了Py_Initialize();。当thread2执行Py_Initialize();时,将清除thread1可能需要的所有信息。我尝试在应用程序启动时调用Py_Initialize(),因此它只会调用一次。但没有奏效。看起来这两个调用在p / invoke调用中是完全隔离的。

我在C中很差并且嵌入了python,有没有人有相关经验?我的项目主持人https://github.com/qianlifeng/WinAlfred如果你们想看到我上面描述的代码。

1 个答案:

答案 0 :(得分:1)

最后,我找到http://pythonnet.github.io/。您可以在此项目WinAlfred中找到详细信息。我解决了这个项目中的多线程问题。