diff --git a/PyWinAlfred.Test/Source.cpp b/PyWinAlfred.Test/Source.cpp index 4f70cb6a41..910f0d8c5c 100644 --- a/PyWinAlfred.Test/Source.cpp +++ b/PyWinAlfred.Test/Source.cpp @@ -23,19 +23,10 @@ char* Exec(char* directory, char* file, char* method, char* para) PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pClass, *pInstance; char *error; - //PyThreadState* global_state = PyThreadState_Get(); - //PyThreadState* ts = Py_NewInterpreter(); - //PyThreadState_Swap(ts); + PyGILState_STATE gstate = PyGILState_Ensure(); + // Initialise the Python interpreter - // Create GIL/enable threads - - PyGILState_STATE gstate = PyGILState_Ensure(); - // // Get the default thread state - // PyThreadState* state = PyThreadState_Get(); - // // Once in each thread - //PyThreadState* stateForNewThread = PyThreadState_New(state->interp); - //PyEval_RestoreThread(stateForNewThread); // Build the name object PyObject *sys = PyImport_ImportModule("sys"); @@ -98,27 +89,36 @@ char* Exec(char* directory, char* file, char* method, char* para) // Finish the Python Interpreter //PyErr_Clear(); - //Py_EndInterpreter(ts); - //PyThreadState_Swap(global_state); - + printf("My thread is finishing... %s \n",para); PyGILState_Release(gstate); return str_ret; } int main(int argc, char *argv[]) { - char* directory = "d:\\Personal\\WinAlfred\\WinAlfred\\bin\\Debug\\Plugins\\p4pperson\\"; + char* directory = "d:\\github\\WinAlfred\\WinAlfred\\bin\\Debug\\Plugins\\p"; char* file = "main"; char* method = "query"; - char* para = "p q"; + char* para1 = "p 1"; + char* para2 = "p 2"; + char* para3 = "p 3"; + char* para4 = "p 4"; + int i = 0; + // 初始化 Py_Initialize(); + // 初始化线程支持 PyEval_InitThreads(); - for(int i=0;i++;i<10){ - auto future = std::async(Exec,directory,file,method,para); - printf("%s",future.get()); - } - Py_Finalize(); +PyEval_ReleaseLock(); + // 启动子线程前执行,为了释放PyEval_InitThreads获得的全局锁,否则子线程可能无法获取到全局锁。 + //std::async(Exec,directory,file,method,para); + std::async(Exec,directory,file,method,para1); + std::async(Exec,directory,file,method,para2); + std::async(Exec,directory,file,method,para3); + std::async(Exec,directory,file,method,para4); + // 保证子线程调用都结束后 + //PyGILState_Ensure(); getchar(); + Py_Finalize(); return 0; } \ No newline at end of file diff --git a/PyWinAlfred/Main.cpp b/PyWinAlfred/Main.cpp index fd61844adc..22f4aeabc9 100644 --- a/PyWinAlfred/Main.cpp +++ b/PyWinAlfred/Main.cpp @@ -7,9 +7,10 @@ int i = 0; extern "C" __declspec(dllexport) void InitPythonEnv() { - i++; Py_Initialize(); PyEval_InitThreads(); + PyEval_ReleaseLock(); + // 启动子线程前执行,为了释放PyEval_InitThreads获得的全局锁,否则子线程可能无法获取到全局锁。 } char* GetErrorMessage() @@ -30,25 +31,11 @@ char* Exec(char* directory, char* file, char* method, char* para) { PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pClass, *pInstance; char *error; - i++; - PyThreadState* global_state = PyThreadState_Get(); - PyThreadState* ts = Py_NewInterpreter(); - PyThreadState_Swap(ts); - // Initialise the Python interpreter - - // Create GIL/enable threads - - //PyGILState_STATE gstate = PyGILState_Ensure(); - // // Get the default thread state - // PyThreadState* state = PyThreadState_Get(); - // // Once in each thread - //PyThreadState* stateForNewThread = PyThreadState_New(state->interp); - //PyEval_RestoreThread(stateForNewThread); + PyGILState_STATE gstate = PyGILState_Ensure(); // Build the name object - PyObject *sys = PyImport_ImportModule("sys"); - PyObject *path = PyObject_GetAttrString(sys, "path"); + PyObject *path = PySys_GetObject("path"); PyList_Append(path, PyString_FromString(directory)); pName = PyString_FromString(file); @@ -102,19 +89,17 @@ char* Exec(char* directory, char* file, char* method, char* para) char * str_ret = PyString_AsString(pValue); - //PyEval_SaveThread(); - - // Finish the Python Interpreter - - PyErr_Clear(); - Py_EndInterpreter(ts); - PyThreadState_Swap(global_state); + //PyErr_Clear(); + PyGILState_Release(gstate); return str_ret; } extern "C" __declspec(dllexport) char* ExecPython(char* directory, char* file, char* method, char* para) { - auto future = std::async(Exec,directory,file,method,para); - return future.get(); + char* s = Exec(directory,file,method,para); + PyGILState_Ensure(); + return s; + //auto future = std::async(Exec,directory,file,method,para); + //return future.get(); } \ No newline at end of file diff --git a/WinAlfred/MainWindow.xaml.cs b/WinAlfred/MainWindow.xaml.cs index 0c3d2aa2c3..7eea9d3832 100644 --- a/WinAlfred/MainWindow.xaml.cs +++ b/WinAlfred/MainWindow.xaml.cs @@ -68,8 +68,8 @@ namespace WinAlfred private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) { string query = tbQuery.Text; - //ThreadPool.QueueUserWorkItem(state => - //{ + ThreadPool.QueueUserWorkItem(state => + { results.Clear(); foreach (PluginPair pair in plugins) { @@ -98,7 +98,7 @@ namespace WinAlfred resultCtrl.AddResults(results.OrderByDescending(o => o.Score).ToList()); resultCtrl.SelectFirst(); })); - //}); + }); } private void HideWinAlfred()