4

I have two threads, one for data acquisition and the other one for display. In order to avoid from unnecessary synchronization. I use double buffering (or page flipping) as following:

  1. data thread is writing buffer 1 while display thread reading the buffer 2
  2. once writing is done for a buffer, data thread switches to the other buffer (buffer 2) and starts writing new page.
  3. For reading, if a buffer is in the middle of writing, display thread reads from the other buffer.

It actually works well but sometimes (1 per 100 frames) I can see tearing in the display which means there is still race condition.

So how can I implement minimal (effective) synchronization of this double buffering? A pseudo algorithm would be enough for me.

Tae-Sung Shin
  • 20,215
  • 33
  • 138
  • 240
  • Unless your GUI library does it for you, you'll also need to synchronize your double-buffering with respect to the refresh signal of the video card. Otherwise it is possible to still see some 'tearing' if the monitor refreshes at the same time you are redrawing your display. – Jeremy Friesner Dec 28 '11 at 03:19

2 Answers2

1

What language, platform and (if necessary) Graphics API are you working with?

A pseudo algorithm would be enough for me.

There is such a variety in approaches depending on the situation, you really should be more specific. For instance, you can declare critical sections so that thread 1 waits when writing while thread 2 is reading, and so on - but there are reasons not to do that.

You could just work with message passing, which would wake up the drawing thread rather than working with critical sections. So it really depends a great deal on language, platform and graphics API.

Here's some code that uses message passing to synchronize the rendering and transfer to graphics:

DataAcquisitionThread.Run() {
  ProcessData();
  Wait(message);
  DrawToBackBuffer();
}

DisplayThread.Run() {
  Wait(message);
  SwapBuffer(message.bufferNumber);
  Render(buffer);
  SendMessage(message.defaultMessage());
}
Keldon Alleyne
  • 2,103
  • 16
  • 23
  • @Paul: I've added an approach with message passing. I used to use it to synchronize audio buffers on a system that didn't have a thread scheduling system (instead sending messages would swap the running thread/process). – Keldon Alleyne Dec 28 '11 at 03:16
1

You can do this with two semaphores. It is a variation of the Producer/Consumer problem. Pseudo-code in the link I provided.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • I didn't use semaphores but simpler queue structure without any lock. It worked perfect. – Tae-Sung Shin Dec 28 '11 at 04:52
  • Hmm. I doubt you solved the problem. Maybe you reduced the chance of a race condition, but without synchronization primitives I doubt you can have a 100% foolproof solution. – Miguel Grinberg Dec 28 '11 at 07:18
  • you are right. My statement was incorrect. Our test is actually passing but I realized that I was using synchronization without noticing it. – Tae-Sung Shin Dec 28 '11 at 17:11