Synchronizing very fast threads

If I understand correctly, you want the 2 threads to work alternately: updater wait until the renderer finish before to iterate again, and the renderer wait until the updater finish before to iterate again. Part of the computation could be parallel, but the number of iteration shall be similar between both.

You need 2 locks:

  • one for the updating
  • one for the rendering

Updater:

wait (renderingLk)
update
signal(updaterLk)

Renderer:

wait (updaterLk)
render
signal(renderingLk)

EDITED:

Even if it look simple, there are several problems to solve:

Allowing part of the calculations to be made in parallel: As in the above snippet, update and render will not be parallel but sequential, so there is no benefit to have multi-thread. To a real solution, some the calculation should be made before the wait, and only the copy of the new values need to be between the wait and the signal. Same for rendering: all the render need to be made after the signal, and only getting the value between the wait and the signal.

The implementation need to care also about the initial state: so no rendering is performed before the first update.

The termination of both thread: so no one will stay locked or loop infinitely after the other terminate.


I think a mutex (alone) is not the right tool for the job. You might want to consider using a semaphore (or something similar) instead. What you describe sound a lot like a producer/consumer problem, i.e., one process is allowed to run once everytime another process has finnished a task. Therefore you might also have a look at producer/consumer patterns. For example this series might get you some ideas:

  • A multi-threaded Producer Consumer with C++11

There a std::mutex is combined with a std::condition_variable to mimic the behavior of a semaphore. An approach that appears quite reasonable. You would probably not count up and down but rather toggle true and false a variable with needs redraw semantics.

For reference:

  • http://en.cppreference.com/w/cpp/thread/condition_variable
  • C++0x has no semaphores? How to synchronize threads?

This is because you use a separate drawing variable that is only set when the rendering thread reacquires the mutex after a wait, which may be too late. The problem disappears when the drawing variable is removed and the check for wait in the update thread is replaced with ! m_rt.readyToDraw (which is already set by the update thread and hence not susceptible to the logical race.

Modified code and results

That said, since the threads do not work in parallel, I don't really get the point of having two threads. Unless you should choose to implement double (or even triple) buffering later.