2013-12-25 20 views
1

내 응용 프로그램은 파이썬 플러그인 시스템을 제공합니다. C#에서 파이썬을 호출하려면. 파이썬 DLL을 포함하는 C 래퍼를 작성했습니다. 여기 요점은 C wrapper gist입니다.멀티 스레드 C# 응용 프로그램에 파이썬 포함하기

그럼 C#에서 P/Invoke를 사용하여 C DLL을 호출합니다. 이와 같이 :

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

위의 코드를 C#으로 작성한 여러 스레드에서 실행하지 않은 경우에는 괜찮습니다. 문제는 스레드를 사용하지 않으면 파이썬 코드를 실행하는 데 오랜 시간이 걸리면서 C#의 주 스레드가 차단된다는 것입니다. 그래서, 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가 좋지 않고 파이썬이 포함되어 있습니다. 관련 경험이있는 사람이 있습니까? 내 프로젝트가 https://github.com/qianlifeng/WinAlfred에 있습니다. 여러분이 위에서 설명한 코드를보고 싶다면.

+1

정확히 원하는 것은 아니지만 IronPython을 .NET 응용 프로그램에 포함시키는 것이 CPython보다 훨씬 쉽습니다. 단점은 IronPython과 잘 작동하지 않는 Python 라이브러리가 있다는 것입니다. – Dirk

+1

Ironpython을 사용해 보았습니다. 말씀 드렸듯이 일부 라이브러리는 제대로 작동하지 않습니다. 예 : 요청. 이것이 현재 CPython을 시도하고있는 이유입니다. – scott

답변

1

마지막으로 http://pythonnet.github.io/을 찾습니다. 자세한 내용은 WinAlfred 프로젝트에서 확인할 수 있습니다. 이 프로젝트에서 다중 스레드 문제를 해결했습니다.

+0

다중 스레드가 pythonnet과 함께 사용되는 wox 코드를 가리킬 수 있습니까? – denfromufa