как синхронизировать двойную буферизацию в многопоточном приложении - PullRequest
4 голосов
/ 28 декабря 2011

У меня есть два потока, один для сбора данных, а другой для отображения.Во избежание ненужной синхронизации.Я использую двойную буферизацию (или перелистывание страниц) следующим образом:

  1. поток данных записывает буфер 1, в то время как поток отображения читает буфер 2
  2. после завершения записи для буфера, потока данныхпереключается на другой буфер (буфер 2) и начинает писать новую страницу.
  3. Для чтения, если буфер находится в середине записи, поток чтения читает из другого буфера.

На самом деле это работает хорошо, но иногда (1 на 100 кадров) я вижу разрыв на дисплее, что означает, что все еще есть состояние гонки.

Так, как я могу реализовать минимальное (эффективное) синхронизация этой двойной буферизации?Мне будет достаточно псевдоалгоритма.

Ответы [ 2 ]

1 голос
/ 28 декабря 2011

Вы можете сделать это с двумя семафорами. Это вариант проблемы Производитель / Потребитель . Псевдокод в предоставленной мной ссылке.

1 голос
/ 28 декабря 2011

На каком языке, платформе и (при необходимости) графическом API вы работаете?

Мне будет достаточно псевдо-алгоритма.

СуществуетРазнообразие подходов в зависимости от ситуации, вы действительно должны быть более конкретными.Например, вы можете объявить критические секции так, чтобы поток 1 ожидал при записи, пока поток 2 читает, и так далее, - но есть причины этого не делать.

Вы можете просто работать с передачей сообщений, чтоРазбудить поток рисунка, а не работать с критическими разделами.Так что это действительно сильно зависит от языка, платформы и графического API.

Вот код, который использует передачу сообщений для синхронизации рендеринга и передачи в графику:

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

DisplayThread.Run() {
  Wait(message);
  SwapBuffer(message.bufferNumber);
  Render(buffer);
  SendMessage(message.defaultMessage());
}
...