Jump to content

    
ARV

Обработка потока данных - как реализуется концептуально?

Recommended Posts

Заголовок темы краткий, поясняю смысл вопроса на примере последовательного порта.

Из порта поступают байты, которые надо обработать. Для обработки используются т.н. фильтры - модули, получающие на вход поток байтов и содержащие список следующих фильтров, куда направляют поток данных со своего выхода. Например, есть фильтр, инвертирующий регистр символов и вырезающий из потока символы перевода строки: получил на входе "AbC\n", выдал на выход "aBc". К выходу этого фильтра подключены еще три фильтра, т.е. после того, как фильтр отработал, строку "aBc" он посылает поочередно на эти три фильтра, каждый из которых тоже может послать результат на следующие фильтры, те - на следующие и т.д.

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

Логически все просто, но есть вопрос быстродействия: если каждый байт будет бродить по дереву, то для обработки следующего байта из порта придется ждать, пока все эти вложенные циклы передачи с выхода на вход (обход ветвей дерева) не закончится. С учетом того, что на самом деле поток обрабатывается не побайтово, а условными строками, т.е. блоками данных 1...X байт (где X в 64-битных системах практически не ограничено, пусть будет 0xFFFF), проблема имеет место быть. К тому же обработка данных внутри фильтра может быть не тривиальной, т.е. длительной.

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

В общем, то ли я сам себе нагоняю мороза в труселя, то ли и вправду проблема есть, и её надо решать. Как вообще концептуально это следует делать? Пока думаю только в приложении к Windows, но теоретически есть задумка и на счет кроссплатформенности...

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

Share this post


Link to post
Share on other sites

FIFO уже на уровне драйвера порта сделано: оттуда уже приходит от 1 до 0xFFFF байтов.

9 минут назад, arhiv6 сказал:

Оставить всё как есть

Считаете, проблема "медленной обработки" за счет постоянного копирования туда-сюда данных, надумана?

Share this post


Link to post
Share on other sites

Сколько времени занимает

1. прием Х байтов ?

2. обработка Х байтов ?

Как только узнаете эти два числа, тогда и будете думать.

Share this post


Link to post
Share on other sites
1 час назад, ARV сказал:

В общем, то ли я сам себе нагоняю мороза в труселя, то ли и вправду проблема есть

Со сферическими конями в вакууме всегда так.  :unknw:

Share this post


Link to post
Share on other sites
2 hours ago, ARV said:

К выходу этого фильтра подключены еще три фильтра,

Неправильные слова приводят к неправильным мыслям. 
Надо отказаться от применения слова фильтр и поток.
Правильне было бы применять слова парсер, лексер и грамматика

 И не некий поток должен пихать данные в обработчик, а обработчик должен брать необходимые данные. 
 

Share this post


Link to post
Share on other sites
1 час назад, x893 сказал:

Сколько времени занимает

1. прием Х байтов ?

2. обработка Х байтов ?

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

Только что, AlexandrY сказал:

Неправильные слова приводят к неправильным мыслям

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

Share this post


Link to post
Share on other sites
46 minutes ago, ARV said:

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

Тогда нужно сделать последнее напряжение и решить, что будет с данными, если обработка ещё не закончилась, а новые данные уже готовы.
Два варианта есть
1. бросить обрабатывать старые и заняться новыми
2. бросить новые и до конца обработать старые.
 

А кто будет пихать или всасывать - не важно.

Share this post


Link to post
Share on other sites
34 minutes ago, x893 said:

А кто будет пихать или всасывать - не важно.

Как это не важно, это принципиальное различие!
Пихать - это одна точка передачи данных.
Всасывать - много точек передачи данных. 
Улавливаете? 
Эт принципиально разные архитектурные решения.  :biggrin:
 

Share this post


Link to post
Share on other sites
8 minutes ago, AlexandrY said:

Как это не важно, это принципиальное различие!
Пихать - это одна точка передачи данных.
Всасывать - много точек передачи данных. 
Улавливаете? 
Эт принципиально разные архитектурные решения.  :biggrin:
 

Пофиг как называть - всос/высос (I/O).
Пусть на на вопрос ответит сначала.
 

Share this post


Link to post
Share on other sites
1 час назад, x893 сказал:

Два варианта есть

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

Share this post


Link to post
Share on other sites
1 hour ago, x893 said:

Пофиг как называть - всос/высос (I/O).
Пусть на на вопрос ответит сначала.
 

Мне видится архитектура как набор асинхронных тредов. Обмен между тредами делается обычно через очереди. 
И в каждой очереди выбор между потерей старых данных или потерей новых данных задается простым флагом.
Так что вопрос о том что теряется как раз вторичный. 
По идее более высокоуровневый тред решает как обходится с данными. Т.е. решение делается динамически.
То есть pull лучше push-а.  
 

Share this post


Link to post
Share on other sites

Пока нет уонкретного ответа, всё это рассуждения о сферическом коне в ваккуме.

Хоть 122 потока создавать, хоть 0.

 

3 hours ago, ARV said:

Я стремлюсь сделать

Зачем создавать тему, если нет ответов, а хрустальные шары на складе закончились.

Share this post


Link to post
Share on other sites
3 часа назад, x893 сказал:

Зачем создавать тему

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

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

Share this post


Link to post
Share on other sites

Достаточно выбросить на помойку прошивку для игровых приставок и перейти на нормальную операционную систему.

Где есть нормальные IPC и т.д., и т.п.!

Да, задачу тоже надо пересмотреть: она явно может быть оптимизирована!

Edited by Eddy_Em

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.