使用FreeGLUT的C ++ TinyThread和OpenGL

时间:2012-12-14 15:41:19

标签: c++ multithreading freeglut

我遇到的问题是由于在简单的FreeGLUT C ++应用程序中可能误用线程而产生的。

由于退出glutMainLoop()不能优雅地完成,我依靠glutLeaveMainLoop()来完成一些工作,但是这个并没有真正将控制权交还给程序的main功能。我有一个全局指针,它将在GL调用之前在main函数中设置为在堆上创建的对象实例。在不使用atexit回调的情况下,没有人会在此实例上调用delete运算符,尽管我在glutMainLoop调用之后放置了这样的操作(现在由于其无效而进行了注释)。

这是我正在做的假代码(我不会发布实际的代码,因为它太长而无法过滤):

CWorld* g_world;

AtExit()
{
 delete g_world;
}
void main()
{
  atexit(AtExit);
  // create an instance of an object that creates a thread in its constructor
  // via the new operator and joins this thread in its destructor
  // calling the delete operator on that pointer to the thread instance
  CWidget thisObjectCreatesATinyThread;

  g_world = new CWorld();
  ...
  glutMainLoop();
  // delete g_world;
}

请注意,在main函数中,我还包含了一个窗口小部件实例,它通过在其构造函数中创建的线程执行某些操作。该线程在其析构函数中连接,然后通过delete释放内存。

错误的行为:如果没有设置atexit回调,我会收到资源泄漏,因为CWorld对象的析构函数不会被调用。如果我设置了这个回调,那么delete运算符会因某种原因被调用两次,即使AtExit函数只被调用一次。

有什么地方可以找到这种奇怪行为的来源?

即使我禁用CWidget实例化,我仍然会得到特殊的行为。

1 个答案:

答案 0 :(得分:1)

我假设您没有使用原始的GLUT库(因为它很古老),而是使用FreeGLUT,这是最广泛的GLUT实现。为了让glutMainLoop()返回,你可以这样做:

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

在调用glutMainLoop()之前。如果在调用glutLeaveMainLoop()时没有更多活动的顶级窗口,这将导致它返回。如果您不关心仍然活动的窗口,请执行以下操作:

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);

您可能必须包含<GL/freeglut.h>而不是<GL/glut.h>才能获得定义。