У меня есть инструмент, который производит поток данных; мой код получает доступ к этим данным через обратный вызов onDataAcquisitionEvent(const InstrumentOutput &data)
. Алгоритм обработки данных потенциально намного медленнее, чем скорость поступления данных, поэтому я не могу надеяться обработать каждый отдельный фрагмент данных (и мне это не нужно), но я хотел бы обработать как можно больше. Благодарю прибор как датчик окружающей среды со скоростью сбора данных, которую я не контролирую. InstrumentOutput
может быть, например, классом, который содержит три одновременных измерения давления в разных местах.
Мне также нужно вести небольшую историю данных. Предположим, например, что я могу разумно надеяться обрабатывать выборку данных каждые 200 мс или около того. В большинстве случаев я был бы счастлив обработать только один последний образец, но иногда мне нужно было бы просмотреть данные за пару секунд, которые поступили до этого последнего образца, в зависимости от того, присутствуют ли аномальные показания в последнем образце.
Другое требование - как можно скорее выйти из onDataAcquisitionEvent()
обратного вызова, чтобы избежать потери данных в датчике.
Библиотека сбора данных (сторонняя) собирает данные прибора в отдельном потоке.
Я подумал о следующем дизайне; иметь очередь одного производителя / одного потребителя и помещать токены данных в синхронизированную очередь в обратном вызове onDataAcquisitionEvent ().
На принимающей стороне существует цикл, который выталкивает данные из очереди. Цикл почти никогда не засыпает из-за высокой скорости поступления данных. На каждой итерации происходит следующее:
- Вытащить все доступные данные из очереди,
- Извлеченные данные копируются в кольцевой буфер (я использовал кольцевой буфер повышения), таким образом всегда доступна некоторая история,
- Обработать последний элемент в буфере (и, возможно, посмотреть на предыдущие),
- Повторить петлю.
Вопросов:
- Насколько хорош этот дизайн и каковы подводные камни? а также
- Что может быть лучше?
Изменить: одна проблема, о которой я подумал, - это когда размер кольцевого буфера недостаточно велик для хранения необходимой истории; в настоящее время я просто перераспределяю кольцевой буфер, удваивая его размер. Надеюсь, мне нужно будет сделать это всего один или два раза.