I’m trying to get a simple multi-threaded OpenGL application working. I have an update thread and a render thread. The way I’ve written them, they should be essentially taking turns running because they are mutex locked. Instead, the update thread will run tens of times, and then the render thread will runs tens of times. Here is the relevant code:
void glRender() {
printf("glRender()\n");
glXMakeCurrent(display, window, glXContext);
glSetup();
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex2f(cosf(fDrawAngle), sinf(fDrawAngle));
glVertex2f(cosf(fDrawAngle+2.1f), sinf(fDrawAngle+2.1f));
glVertex2f(cosf(fDrawAngle+4.2f), sinf(fDrawAngle+4.2f));
glEnd();
glXSwapBuffers(display, window);
glXMakeCurrent(display, 0, 0);
}
void * glThread(void * params) {
while (bRunning) {
pthread_mutex_lock(&mutex);
glRender();
pthread_mutex_unlock(&mutex);
}
pthread_exit(0);
}
// Multi threaded version
void gameUpdateMT() {
while (bRunning) {
pthread_mutex_lock(&mutex);
printf("gameUpdate()\n");
windowUpdate();
fDrawAngle += 0.01f;
pthread_mutex_unlock(&mutex);
}
}
// Single threaded version - Runs fine.
void gameUpdateST() {
while (bRunning) {
printf("gameUpdate()\n");
windowUpdate();
fDrawAngle += 0.01f;
glRender();
}
}
gameUpdateMT() and glThread() are running in parallel. What would be causing one thread to loop so many times before the other one gets a chance to run?
A thread doesn’t necessarily end its timeslice when it calls
pthread_mutex_unlock(). This being the case, it can easily loop around again and re-acquire the mutex (the waiters on a mutex aren’t queued).It’s possible to use a condition variable to have the threads take turns – but that’s just needlessly overcomplicating things. If you want
glRender()andwindowUpdate()called alternately in sequence, then just have a single thread call them alternately, just as in your “singlethreaded” version.There’s no point having multiple threads if they never run concurrently.