因此,我們試圖在一個進程內建立一個搶佔式的實時系統,將每個任務作爲一個單獨的線程執行。爲了構建GUI,SDL是選擇的庫,我們將GUI初始化與渲染分開,以便後者可以是不同的任務。儘管SDL有自己的線程,但我們使用了pthreads
。發現的信息是矛盾的,因爲一些消息來源指出渲染不能在不同的過程中執行,而另一些消息則另外聲明。但是,在Debian中使用虛擬機時,渲染已正確執行,但在Raspberry Pi中通過改變主線程和渲染線程之間的上下文來執行,SDL_GetError()
不會返回錯誤,但不會呈現導致黑色窗口的任何內容一個遊標。說明主線程中的渲染在Pi和虛擬機中按照預期工作是很重要的。樹莓派上的多線程SDL2渲染2
爲了解決這個問題,在Pi和SDL配置中使用了幾種替代方案。關於皮本身,使用sudo raspi-config
,完全和假KMS來啓用OpenGL不與不同的錯誤工作被提出:
全KMS - Could not initialize OpenGL/GLES library*
假KMS - * failed to add service - already in use?
(鍵盤停止工作) 。
已禁用OpenGL(原點) - 沒有錯誤,黑色窗口未渲染。
下面的代碼存在,每線程:
主線程:
SDL_Window* GUI_init(int w, int h) {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fprintf(stderr, "Cannot initialise SDL: %s\n", SDL_GetError());
exit(1);
}
window = SDL_CreateWindow(
"Tron",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
w, h,
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL
);
if (window == NULL) {
fprintf(stderr, "Unable to create window: %s\n", SDL_GetError());
exit(1);
}
globalRenderer = SDL_CreateRenderer(
window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
);
if (globalRenderer == NULL) {
fprintf(stderr, "Unable to create renderer: %s\n", SDL_GetError());
exit(1);
}
if (SDL_SetRenderDrawBlendMode(globalRenderer, SDL_BLENDMODE_BLEND) != 0) {
fprintf(stderr, "SDL_BlendMode failed: %s\n", SDL_GetError());
exit(1);
};
ctx = SDL_GL_CreateContext(window);
if(ctx == NULL) {
fprintf(stderr, "Unable to create context: %s\n", SDL_GetError());
exit(1);
}
int ctx1 = SDL_GL_MakeCurrent(window,NULL);
if(ctx1!=0) {
fprintf(stderr, "Unable to make currents context: %s\n", SDL_GetError());
exit(1);
}
//return globalRenderer;
return window;
}
渲染線程:
void* GUI_update(void* params) {
SDL_GL_MakeCurrent(window,ctx);
GUI_setRenderDrawColor(globalRenderer);
SDL_RenderClear(globalRenderer);
GUI_fillBoardBorders(globalRenderer);
GUI_fillBoard(globalRenderer);
SDL_RenderPresent(globalRenderer);
}
利用3個全局變量:
SDL_Window *window = NULL;
SDL_GLContext ctx = NULL;
SDL_Renderer* globalRenderer = NULL;
我們e使用Raspbian Jessie Lite作爲操作系統。這裏可能是什麼問題?
對於GUI庫來說,所有操作都必須在同一個線程中執行是非常典型的,我真的不認爲SDL在這裏是一個例外...... –
大多數消息來源指出GUI庫不是線程安全的,但我覺得奇怪是它按照Debian的預期工作,而不是Raspbian,這讓我相信這是可行的。 –
你可以隨時有東西沒有線程安全「工作」在意外 –