在我的应用程序中,我有一个运行应用程序的简单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(),最后是对阻塞函数的调用 接受()。
同样,这个服务器,以及渲染和所有内容,在附加调试器时都能正常工作,只有在“直接”启动它才会挂起(强制我杀死进程以阻止它)。
服务器和应用程序没有通用的数据结构,服务器对App没有任何了解, 两者之间唯一的关系是App在Server上设置了一个回调函数。
mServer->Callback = [this](Command cmd){ this->CommandReceived(); });
编辑(追加):这只发生在我的电脑上,我的笔记本电脑上有完全相同的设置(ubuntu,gcc,sdl等相同),它在我的笔记本电脑上工作正常。 请注意确定是否/如何相关,但我在Windows 8上的Hyper-V虚拟机中运行Ubuntu,如果有任何帮助的话。