Проблема, с которой я столкнулся, вызвана вероятным неправильным использованием потоков в упрощенном приложении FreeGLUT C ++.
С выходом glutMainLoop()
не может быть сделано элегантно, я полагаюсь на glutLeaveMainLoop()
чтобы сделать часть работы, но этот на самом деле не возвращает контроль над программой main
функция. У меня есть глобальный указатель, который будет установлен в main
Функция, до вызовов GL, к экземпляру объекта, созданному в куче. Без использования 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;
}
Обратите внимание, что в основную функцию я также включил экземпляр виджета, который выполняет некоторую работу через поток, созданный в его конструкторе. Этот поток объединяется в своем деструкторе, затем память освобождается через delete
,
Неправильное поведение: без настройки atexit
обратный вызов, я получаю утечку ресурсов, так как деструктор CWorld
объект не будет вызван. Если я установлю этот обратный вызов, то delete
Оператор вызывается дважды по какой-то причине, хотя AtExit
Функция вызывается только один раз.
Где найти источник этого странного поведения?
Даже если я отключу инстанцирование CWidget, я все равно получаю своеобразное поведение.
Я предполагаю, что вы используете не оригинальную библиотеку 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>
для того, чтобы получить определения.
Других решений пока нет …