[英]How to acquire GIL for the new thread state created using embed python in C++ application
我有一個 C++ 應用程序,我們提供了一個 python 編輯器(使用 python 3.7),用戶可以在編輯器中輸入和執行 python 代碼。 以下是我們在執行用戶提供的腳本之前創建新線程狀態並使其成為當前狀態的示例代碼。
#include <python.h>
PyThreadState* globalthread;
void executescript()
{
PyEval_SaveThread();
PyThreadState* ts = PyThreadState_New(globalthread->interp);
int gilstate = PyGILState_Check(); //check whether GIL is with current thread or not
if (!gilstate)
{
PyEval_RestoreThread(ts);
}
else
{
PyThreadState_Swap(ts);
}
// get the thread state with which GIL is currently assigned
PyThreadState * gilthreadstate = PyGILState_GetThisThreadState();
//----> the above line return pointer to global thread state (gilthreadstate == globalthread)
//----> which means the GIL is not acquired by the new current thread
gilstate = PyGILState_Check(); //results in zero as GIL is not with current thread
std::string str = "def script():\n\timport sys\n\tsys.path.append('C:\\Python\\Python37\\Lib\\site-packages')\n\tprint(sys.path)\n\timport numpy\n\tarr = numpy.array([1, 2, 3, 4, 5])\n\tprint(arr)\nscript()";
PyRun_SimpleString(str.c_str());
PyThreadState_Clear(ts);
PyThreadState_DeleteCurrent();
PyEval_RestoreThread(globalthread);
//following stmt returns 1 as the current thread is global thread and it has GIL with it
gilstate = PyGILState_Check();
}
int main()
{
Py_Initialize();
PyEval_InitThreads();
globalthread = PyThreadState_Get();
executescript();
PyThreadState_Swap(globalthread);
Py_FinalizeEx();
return 0;
}
當 PyEval_RestoreThread 或 PyThreadState_Swap 被調用時,新的當前線程不會獲取 GIL。 因此,具有import numpy
或import pandas
Python 腳本將以死鎖告終。 有人可以讓我知道如何為新線程狀態或代碼錯誤獲取 GIL 嗎?
hn-1-8e9-wheres-my-share-m的評論通過創建一個新的 C++ 線程解決了這個問題。 這是我修改后的代碼。
#include <python.h>
#include <thread>
PyThreadState* globalthread;
void execute()
{
PyThreadState* ts = PyThreadState_New(globalthread->interp);
int gilstate = PyGILState_Check();
if (!gilstate)
{
PyEval_RestoreThread(ts);
}
else
{
PyThreadState_Swap(ts);
}
std::string str = "def script():\n\timport sys\n\tsys.path.append('C:\\Python\\Python37\\Lib\\site-packages')\n\tprint(sys.path)\n\timport numpy\n\tarr = numpy.array([1, 2, 3, 4, 5])\n\tprint(arr)\nscript()";
PyRun_SimpleString(str.c_str());
PyThreadState_Clear(ts);
PyThreadState_DeleteCurrent();
}
int main()
{
Py_Initialize();
globalthread = PyThreadState_Get();
PyEval_SaveThread();
std::thread t(executePythonScript);
t.join();
PyEval_RestoreThread(globalthread);
//PyThreadState_Swap(globalthread);
Py_FinalizeEx();
return 0;
}
感謝您指出帖子。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.