Синхронизировать два потока - PullRequest
0 голосов
/ 28 января 2020

Есть две темы data_collect_thread и data_process_thread.

data_collect_thread собирает данные и помещает данные в очередь, которая в 4 раза быстрее, чем data_process_thread, который удаляет данные из очереди и обрабатывает их.

В этом состоянии куча переполняется через некоторое время из-за более медленной очереди по сравнению с передачей данных в очередь.

Я не могу ждать в data_collect_thread, пока data_process_thread не обработает данные. Мне нужно получать данные в реальном времени без каких-либо пропусков.

Пожалуйста, предложите алгоритм, чтобы избежать этой проблемы?

Подробнее:

Очередь является двусвязным списком, поэтому мне нужно выделить память в куче, а pu sh - в очередь. После удаления память освобождается.

Ответы [ 3 ]

0 голосов
/ 28 января 2020

Представьте, что у вас есть резервуар для воды, в который вы непрерывно закачиваете воду. Вы также берете воду из резервуара через маленькую трубу. Если вы не удаляете воду с большей скоростью, чем вы ее закачиваете, бак всегда переполнится, рано или поздно. То же самое верно в обработке данных. Вы должны использовать данные со скоростью, равной или превышающей скорость, с которой вы их производите, иначе рано или поздно вам не хватит памяти. Это факт жизни.

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

Поскольку вы говорите, что не контролируете скорость, с которой поступают данные, единственный другой вариант - оптимизировать data_process_thread(), чтобы он работал быстрее, чем скорость поступления данных. 2,5 мс - это достаточно хорошее время для обработки. Внимательно посмотрите на свой код обработки и профилируйте его, чтобы понять, на что он тратит процессорное время. Затем попытайтесь оптимизировать его, чтобы он работал быстрее.

PS: Я только что видел в ваших комментариях, что вы читаете из I2 C. Предполагая, что вы или какой-то другой встроенный микроконтроллер, попробуйте использовать DMA для копирования данных в память с периферийного устройства I2 C, если ваш микроконтроллер поддерживает это. Уменьшение количества прерываний, вероятно, освободит вам больше процессорного времени для обработки.

0 голосов
/ 28 января 2020

У вас есть два варианта:

  • Обрабатывать все данные.
  • Не обрабатывать все данные.

Если вы хотите чтобы обработать все данные, вам нужно обрабатывать их так быстро, как они поступают. Таким образом, вам нужен либо более быстрый компьютер, либо несколько компьютеров, либо более быстрый алгоритм обработки. Полная остановка. Это единственное, что вы можете сделать.

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

Это ваши варианты. Выберите один.

0 голосов
/ 28 января 2020

Вопрос слишком широкий, чтобы дать конкретный c ответ, но в любом случае он достаточно интересен. Поэтому я дам несколько решений.

  • Купите компьютер, который в четыре раза быстрее.
  • Создайте больше экземпляров data_process_thread. Может работать, если у вас несколько ядер.
  • Оптимизировать алгоритм и / или код для data_process_thread.
  • Переписать data_process_thread полностью для запуска на графическом процессоре.
  • Создать кластер компьютеров с балансировщиком нагрузки.
  • Буфер очереди на диск. Может сработать, если вы получите некоторые паузы в потоке данных.

Я мог бы добавить, что если вы добавите достаточно ограничений для вашей проблемы, это может оказаться неразрешимым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...