2012-12-14 52 views
0

我遇到的問題是由於簡單的FreeGLUT C++應用程序中可能的線程濫用而產生的。C++ TinyThread和帶有FreeGLUT的OpenGL

由於退出glutMainLoop()不能做到優雅,我靠glutLeaveMainLoop()做了一些工作,但是這並沒有真正給控制權交還給程序的main功能。我有一個全局指針,將在GL調用之前在main函數中設置爲在堆上創建的對象實例。在沒有使用atexit回叫的情況下,雖然我在glutMainLoop呼叫之後放置了這樣的操作(現在因其無效而被評論),但沒有人會在此實例上呼叫delete運營商。

下面是我在做什麼僞代碼(我不會發布實際的代碼,因爲它太長過濾):

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實例化,我仍然得到了特殊的行爲。

+0

爲什麼要在使用線程時使用* global *變量? –

+0

由於FreeGLUT庫。它需要某種全局變量來控制並傳遞數據給渲染函數。當涉及渲染或怠速時(例如,在這種情況下顯示回調),其回調函數無法與任何參數一起使用。 – teodron

+0

那麼爲什麼你使用FreeGLUT庫需要一個全局變量(我敢打賭它不)? –

回答

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>爲了得到定義。

+0

謝謝,它從主循環返回的意義上按預期工作。析構函數仍然被調用兩次;我會再次檢查它,禁用多線程,並看看如何解決。 – teodron

+0

問題解決了,非常感謝 - FreeGLUT正在將控制返回到主函數,並且資源現在始終得到清理。 – teodron

相關問題