crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
mezmay
  опции профиля:
сообщение 12.12.2012, 19:27
Сообщение #1


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


Наверное любой опытный программист сталкивался с задачей, когда надо использовать два рабочих буфера. Например обработка события получения данных - приняли массив данных, его надо обработать какой-то длительной процедурой и выдать без разрывов, к примеру, на выход звуковой платы. В такой ситуации могут использоваться два рабочих буфера - по принципу "один обрабатываем, второй воспроизводим. потом меняем местами". Вроде все просто, но я такое никогда не реализовывал. Подскажите, это правильно?:

void onReceiveData(QByteArray data)
{
    audioOutput->start(oldArray); // Асинхронная фукнция воспроизведения
    QByteArray newArray = dataDecodeFunction(data); // Довольно длинная синхронная функция обработки данных
    oldArray = newArray;
}

Прошу прокомментировать данный пример. Понял ли я принцип?

Сообщение отредактировал mezmay - 12.12.2012, 19:47
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 12.12.2012, 19:53
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


в твоём примере нет параллельности. вероятно, воспроизведение должно быть запущено параллельно декодированию данных. иначе зачем вообще два буфера? или "асинхронная функция" подразумевает запуск в отдельном потоке?
вызов идёт через копирование объекта, то есть, гигантский массив будет копироваться при каждом вызове. иначе (если бы это была ссылка), следующая операция запортит объект.
объекты создаются и разрушаются, передаются через стек, на это нужно время и реорганизация памяти. для быстрой работы логичнее выделить статический буфер. а его размер корректировать, при необходимости, но не каждый раз. и манипулировать указателями или ссылками.

обычно делается два потока: на чтение и на запись. и мьютексы (ну или сигналы, если это Qt), которые сообщают о состоянии буферов.
потоки ждут сигнала о (заполнении буфера) для чтения или освобождении буфера (для записи). регулирование этого дела зависит от особенностей конкретной задачи.

Сообщение отредактировал Iron Bug - 12.12.2012, 19:58
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mezmay
  опции профиля:
сообщение 12.12.2012, 20:00
Сообщение #3


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


в твоём примере нет параллельности. вероятно, воспроизведение должно быть запущено параллельно декодированию данных

Вопросизведение стартует в новом потоке и сразу начинается декодирование в данном потоке.

То что манипулировать надо указателями - это понятно, здесь речь идет о принципе.

Сообщение отредактировал mezmay - 12.12.2012, 20:01
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 12.12.2012, 20:11
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


о принципе - это смотря чего ты хочешь добиться. у тебя в данном случае непрерывность воспроизведения не гарантирована: то есть, пока идёт декодирование какого-то количества данных, на выходе данные могут банально закончиться и будет пауза.
обычно для непрерывности всё-таки есть один кольцевой буфер и два потока оттуда читают и пишут, по необходимости. у меня, например, куча таких случаев на работе: с устройства идёт поток данных, драйвер его режет на куски и скармливает юзеру. есть две проблемы: чтобы буфер не переполнился и чтобы юзеру данные скармливались более-менее равномерно, без резких скачков и пауз.

Сообщение отредактировал Iron Bug - 12.12.2012, 20:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mezmay
  опции профиля:
сообщение 12.12.2012, 20:15
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


Цитата
чтобы буфер не переполнился и чтобы юзеру данные скармливались более-менее равномерно

Можно предельно простой пример этого?

Цитата
пока идёт декодирование какого-то количества данных, на выходе данные могут банально закончиться
Ну тут уж ни какой алгоритм не гарантирует непрерывность

Сообщение отредактировал mezmay - 12.12.2012, 20:18
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 12.12.2012, 20:26
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


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

на самом деле, сигнал об изменении указателя чтения обычно не требуется. потому что в любом случае чтение должно быть шустрее, чем запись. иначе буфер будет переполняться и данные будут потеряны. и всё это должно быть сдобрено мьютексами для защиты обращения к указателям, чтобы одновременно не происходили запись и чтение оных, а то может получиться бардак.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 14.5.2025, 11:04