在我的应用程序中,我有一个运行应用程序的简单 Execute 方法,大大简化了,它看起来像这样:
App::Execute()
{
Initialize();
SDL_Event event;
While(Running)
{
while(SDL_PollEvent(&event) > 0)
{
HandleEvent(&event);
}
Render();
}
}
Render() 看起来像这样,再次简化:
App::Render()
{
SDL_FillRect(MainSurface, NULL, 0x000000); // MainSurface is declared inside the class
// mCurrentScreen->Render(MainSurface);
SDL_Flip(MainSurface);
}
现在,当附加调试器时这工作正常,但是当我只运行可执行文件时,应用程序冻结,将 gdb 附加到进程,我可以告诉主线程卡在 SDL_Flip() 中。
我已经设法将这个问题缩小到我启动一个单独的线程来监听使用套接字的客户端,因为注释掉第二个线程的开始,使它在所有模式下工作!
线程在“服务器”类中像这样启动:
Server::Start()
{
mThread = std::thread([this](){ListenThread(this); });
}
ListenThread 执行通常的套接字设置 getaddrinfo()、socket()、bind()、listen(),最后调用阻塞函数 accept()。
同样,当附加调试器时,此服务器以及渲染和所有内容都可以完美运行,只有在“直接”启动时它才会挂起(迫使我 KILL 进程停止它)。
Server和App没有共同的数据结构,Server对App一无所知,两者的唯一关系就是App在Server上设置了回调函数。
mServer->Callback = [this](Command cmd){ this->CommandReceived(); });
编辑(附加):这只发生在我的电脑上,我的笔记本电脑上有完全相同的设置(ubuntu、gcc、sdl 版本等),它在我的笔记本电脑上运行良好。请注意它是否/如何相关,但我在 Windows 8 上的 Hyper-V 虚拟机中运行 Ubuntu,如果这有帮助的话。