我刚刚开始学习多线程,我知道示例应用程序 - 我正在研究 - 在使用线程时甚至可能会降低性能。使用的编译器是 GCC4.7 ,带有以下标志: -std = c ++ 0x -g -O3 -Wall
因此我正在使用C ++ 11并使用std :: thread实现。一般来说,我尝试开发跨平台,所以我在大学计算机上的Windows上使用GCC4.7以及在家用机器上使用Ubuntu / Mac OSX进行开发。为了能够跨平台处理Window创建,我使用了SFML库(2.0)。
这里是简化的CApp类和相关函数:
class CApp
{
public:
//! Constructor.
CApp(void);
//! Deconstructor.
~CApp(void);
/* Public Functions: */
//! Initializer function, needs to be called before Run-Function to allocate everything and set everything up.
bool Initialize(unsigned int width, unsigned int height, char* title, bool vsync, CState* startState);
void Run(void); //!< Starts the game-loop
private:
void ProcessEvent(sf::Event event);
sf::RenderWindow* m_pWindow; //!< window instance
std::vector<std::thread> m_threads;
};
一般来说,我的应用程序是一个小型的OpenGL演示场景,它应该是多线程的,以便能够对多线程适合的位置和不适合的位置进行基准测试和比较。
相关功能的实现:
void CApp::Run(void)
{
while (m_pWindow->IsOpen())
{
sf::Event event;
while (m_pWindow->PollEvent(event))
{
m_threads.push_back(std::thread(&CApp::ProcessEvent, this, event));
}
// ...
m_threads.clear();
}
}
void CApp::ProcessEvent(sf::Event event)
{
if (event.Type == sf::Event::Closed)
m_pWindow->Close();
if (event.Type == sf::Event::KeyPressed)
{
if (event.Key.Code == sf::Keyboard::Escape)
m_pWindow->Close();
}
}
我得到的运行时错误只是一个Abort陷阱:第一帧上的6: _“在没有活动异常的情况下调用终止 - 程序收到信号SIGABRT,已中止。 __pthread_kill()“_
中的0x00007fff8fdf4ce2如果我取消了线程创建并在当前线程中调用ProcessEvent,则不会出现问题,因此问题必须与线程相关。
SFML并非全部都是线程安全的,所以我假设问题是m_pWindow-Pointer或事件作为函数参数本身,但我该如何解决这个问题?
答案 0 :(得分:3)
在清除向量并删除所有线程之前,您一定要等待所有线程完成:
void CApp::Run(void)
{
while (m_pWindow->IsOpen())
{
sf::Event event;
while (m_pWindow->PollEvent(event))
{
m_threads.push_back(std::thread(&CApp::ProcessEvent, this, event));
}
for(auto& i : m_threads)
i.join();
m_threads.clear();
}
}
此外,当您使用GCC时,我建议使用-pthread
选项进行编译。