2013-04-02 33 views
0

我是新的C++ concurrency.I開始升壓主題爲我所看到的迄今爲止處理通過單獨的函數到threads.Like this例如例子供那些跨平臺solution.Most工作。在我的例子中,我有一個類有更多類的實例,在我的情況下,OpenGL上下文和渲染相關的東西。 我已經瞭解到,分配一個對象的線程完成這樣:升壓線工人類對象

mythread=new boost::thread(boost::ref(*this)); 

其中*這是指向內部調用它的實例。 但是這個類實例中的其他類又是怎樣的呢?我應該對它們中的每一個都做同樣的事情,或者一旦我在主機類上調用它們,就會自動進行線程化處理? 我的原始問題在this線程中列出。所以,一旦我啓動線程,它看起來像OpenGL上下文保留在主線程中(請參閱底部的GPUThread類)。

這裏是我的線程類:

GPUThread::GPUThread(void) 
    { 
     _thread =NULL; 
     _mustStop=false; 
     _frame=0; 


     _rc =glMultiContext::getInstance().createRenderingContext(GPU1); 
     assert(_rc); 

     glfwTerminate(); //terminate the initial window and context 
     if(!glMultiContext::getInstance().makeCurrent(_rc)){ 

     printf("failed to make current!!!"); 
     } 
     // init engine here (GLEW was already initiated) 
     engine = new Engine(800,600,1); 

    } 
    void GPUThread::Start(){ 



     printf("threaded view setup ok"); 

     ///init thread here : 
     _thread=new boost::thread(boost::ref(*this)); 
     _thread->join(); 

    } 
void GPUThread::Stop(){ 
    // Signal the thread to stop (thread-safe) 
    _mustStopMutex.lock(); 
    _mustStop=true; 
    _mustStopMutex.unlock(); 

    // Wait for the thread to finish. 
    if (_thread!=NULL) _thread->join(); 

} 
// Thread function 
void GPUThread::operator()() 
{ 
     bool mustStop; 

     do 
    { 
     // Display the next animation frame 
     DisplayNextFrame(); 
     _mustStopMutex.lock(); 
     mustStop=_mustStop; 
     _mustStopMutex.unlock(); 
    } while (mustStop==false); 

} 


void GPUThread::DisplayNextFrame() 
{ 

    engine->Render(); //renders frame 
    if(_frame == 101){ 
     _mustStop=true; 
    } 
} 

GPUThread::~GPUThread(void) 
{ 
    delete _view; 
    if(_rc != 0) 
    { 
     glMultiContext::getInstance().deleteRenderingContext(_rc); 
     _rc = 0; 
    } 
    if(_thread!=NULL)delete _thread; 
} 

當這個類是運行OpenGL背景下發出errors.I不能從buffers.I讀像素數據,假設這是因爲我的init _RC(渲染上下文)和調用此之前設置當前環境:

_thread=new boost::thread(boost::ref(*this)); 

我試過線程初始化後,這樣做,但那麼它跳過直接進入線程函數留下未初始化的對象。 那麼什麼是正確的方式來設置所有內容的類的助推線程?

+0

C++ 11也爲線程提供了跨平臺解決方案。 – David

+0

我目前無法移動到C++ 11,因爲我有一些舊的庫。 –

+0

我感到困惑的GPUThread :: Start()函數。主線程大概是調用GPUThread :: Start(),然後在調用'_thread-> join()'時阻塞。所以你只有一個線程運行? –

回答

1

簡短的回答:你需要OpenGL的通話glMultiContext::getInstance().makeCurrent(_rc),以及可能還有new Engine()呼叫從GPUThread構造遷入GPUThread::operator()()開始。

較長的答案:看來,OpenGL上下文以某種方式綁定到特定的線程,指示here。您需要在您想要將上下文綁定到的線程中運行時調用makeCurrent()您當前運行的線程是makeCurrent()的(完全隱含)參數。

您正在從主線程調用GPUThread構造函數,然後從主線程調用GPUThread::Start()。實際上在子線程上運行的第一個位置在GPUThread::operator()()函數的頂部。所以這是必須撥打glMultiContext::getInstance().makeCurrent(_rc)的地方(在撥打engine->Render()之前)。

我不明白OpenGL的makeCurrent()設計的基本原理。我最好的猜測是,他們必須在實現OpenGL上下文中使用某種線程本地存儲,或者其他什麼。 「正常的」2D Windows「設備上下文也受限於綁定到單個線程,這導致我猜測OpenGL可能有類似的限制。