Python Pybind11函数调用阻塞主线程

Python Pybind11函数调用阻塞主线程,python,c++,python-multithreading,gil,pybind11,Python,C++,Python Multithreading,Gil,Pybind11,我使用pybind11向python公开(用c++编写) 首先我要做的是,通过在C++部分中公开一个启动函数来基本上启动游戏。到目前为止看起来是这样的(c++): #定义NOMINMAX #包括“GameWinMain.h” #包括“GameEngine.h” #包括 #包括“反向h” #包括 名称空间py=pybind11; 使用名称空间std; #定义游戏引擎(GameEngine::GetSingleton()) int start() { //为调试生成启用运行时内存泄漏检查。 #如果已

我使用pybind11向python公开(用c++编写)

首先我要做的是,通过在C++部分中公开一个启动函数来基本上启动游戏。到目前为止看起来是这样的(c++):

#定义NOMINMAX
#包括“GameWinMain.h”
#包括“GameEngine.h”
#包括
#包括“反向h”
#包括
名称空间py=pybind11;
使用名称空间std;
#定义游戏引擎(GameEngine::GetSingleton())
int start()
{
//为调试生成启用运行时内存泄漏检查。
#如果已定义(调试)|已定义(_调试)
_CRTSETDBG标志(_CRTDBG_ALLOC_MEM_DF|u CRTDBG_LEAK_CHECK_DF);
#恩迪夫
WinMain(GetModuleHandle(0),0,0,SW_-SHOW);
返回0;
}
int_tmain()
{
start();
}
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、PSTR szCmdLine、int iCmdShow)
{
if(GAME_ENGINE==NULL)返回FALSE;//创建游戏引擎,如果失败则退出
GAME_ENGINE->SetGame(new Contra());//实现AbstractGame的任何类
cout Run(hInstance,iCmdShow);//运行游戏引擎并返回结果
}
PYBIND11_模块(相反,m)
{

cout这是因为Python的GIL(全局解释器锁)的缘故。您可以阅读更多关于它的内容

如果你想修复这个问题,你应该在C++代码中手动释放吉尔,如

中描述的那样。 简而言之,您可以像下面这样更改启动方法,以避免Python线程被阻塞:

#include <python.h>

class GilManager
{
public:
   GilManager()
   {
      mThreadState = PyEval_SaveThread();
   }

   ~GilManager()
   {
      if (mThreadState)
         PyEval_RestoreThread(mThreadState);
   }

   GilManager(const GilManager&) = delete;
   GilManager& operator=(const GilManager&) = delete;
private:
   PyThreadState* mThreadState;
};

int start()
{
   GilManager g;
    // Enable run-time memory leak check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
    WinMain(GetModuleHandle(0), 0, 0, SW_SHOW);

    return 0;
}
#包括
班级经理
{
公众:
经理()
{
mThreadState=PyEval_SaveThread();
}
~GilManager()
{
if(mThreadState)
PyEval_RestoreThread(mThreadState);
}
GilManager(const GilManager&)=删除;
GilManager&运算符=(const GilManager&)=删除;
私人:
PyThreadState*mThreadState;
};
int start()
{
吉尔格经理;
//为调试生成启用运行时内存泄漏检查。
#如果已定义(调试)|已定义(_调试)
_CRTSETDBG标志(_CRTDBG_ALLOC_MEM_DF|u CRTDBG_LEAK_CHECK_DF);
#恩迪夫
WinMain(GetModuleHandle(0),0,0,SW_-SHOW);
返回0;
}

工作得很好。谢谢!@MatheusZickuhr总是在stackoverflow中使用向上投票来说“谢谢”;-)