2015-01-03 86 views
0

我正在處理SDL2的渲染庫,當我嘗試對渲染器執行任何操作時,我正遇到seg故障。經過調試我已經確定,它從窗口(現...)正確創建但是我想不通爲什麼SDL2是賽格斷層,當我打電話SDL_RenderClear(data->renderer)SDL2 Threading Seg Fault

主線程調用:

int RenderThread::start(std::string title, int x, int y, int w, int h, Uint32 flags) { 
    data.window = SDL_CreateWindow(title.c_str(), x, y, w, h, flags); 
    if(data.window == NULL) return -2; 
    data.renderer = SDL_CreateRenderer(data.window, -1, 0); 
    if(data.renderer == NULL) return -3; 
    data.rlist->setRenderer(data.renderer); 

    data.run = true; 

    if(thread == NULL) 
     thread = SDL_CreateThread(renderThread, "RenderThread", (void*)(&data)); 
    else return 1; 

    return 0; 
} 

然後實際的線程是:

int RenderThread::renderThread(void* d) { 
    RenderData* data = (RenderData*)d; 
    data->rlist->render(true); 
    SDL_SetRenderDrawColor(data->renderer, 0xFF, 0xFF, 0xFF, 0xFF); 
    SDL_RenderClear(data->renderer); 
    while(data->run) { 
     data->rlist->render(); 
     SDL_RenderPresent(data->renderer); 
     SDL_Delay(data->interval); 
    } 
    return 0; 
} 

如果你需要看到更多的是對所有的github代碼。

回答

1

某些平臺(例如Windows)不允許與創建它們的線程之外的線程進行交互。

documentation明確地這樣說:

注意:你不應該指望能夠創建一個窗口,渲染,或除主之外的任何線程接收事件。


從設計的角度來看,試圖從另一個線程渲染成爲諸多問題的根源。例如:

  • 是否需要(不可預知地)每幀更新一個對象?什麼是阻止邏輯線程嘗試進行許多無法呈現的更新?
  • 在沒有機會更新對象的情況下冒險重新渲染風險是否可取?
  • 當更新發生時你會鎖定整個場景嗎?或者每個對象都會獲得自己的鎖,因此您不會嘗試渲染處於更新中的對象?由於其他線程鎖定對象,幀速率是不可預知的嗎?

更不用說同步原語的成本了。

+0

謝謝,將SDL調用移動到線程工作。雖然我會爭辯說,一個單獨的線程是有利的,所以在處理遊戲邏輯時仍然可以渲染。唯一不可能的事情就是無法做到。而且,通過C++包裝,可以爲多個線程訪問的變量提供足夠的保護。 – Eadword