Оригинальное сообщение от Paramedic
Получаю я данные неким блоком. В отдельном потоке. Сижу и жду waitforsingleobject. Как только дождался, данные в файл. Вот они лежат себе в файле, а нужно
1. Рисовать графики (во множественном числе)
2. Принимать решение о воздействии на управляющие органы
При этом частота сбора довольно велика. И я вообще сомневаюсь, что можно успеть нарисовать что либо. Причём, рисовать нужно не всё подряд. Это было бы легко, а вычленять из потока данных некий процесс. Причём процесс этот не будет любезно ложиться в полученный буфер. Возможно он только начнётся. А дорисовывать его придётся только после получения очередной порции. Вот сижу и думаю, чего такого прикрутить, чтобы оно с этими полученными данными работало, терпеливо ждало, если их ещё не хватает, и догоняло, если отстало.
По-моему, ты уже сам полностью описал алгоритм, который остается только описать на языке программирования...
А именно, используем несколько потоков, каждый из которых является узкоспециализированным.
"Поток 1" принимает данные (тот самый твой waitforsingleobject работает). Но ни в какой файл он их не кладет!!! Эта задача убъет всю производительность.
Как только данные получены (или сработал таймер у waitforsingleobject), данные выкладываются в буфер и функцией ResumeThread включаются ранее созданные "Поток 2" ("записыватель" - запись данных в файл) и "Поток 3" ("отображатель" - отображение данных на экране). Эти 2 потока берут данные из буфера.
И дальше ты уже можешь оптимизировать каждый из потоков.
Например, "Поток 2" может выкладывать данные в файл не сразу после получения, а после накопления какой-то "весомой" порции. Для того, чтобы уменьшить количество дисковых операций. А "Поток 1" в это время работает независимо, собирает данные...
Аналогично и "Поток 3" фильтрует "базар" и по указанным тобой критериям либо пропускает данные, либо выводит их на экран.
Можно даже сделать так, что 3-й поток занимается только фильтрацией данных для отображения и передает отфильтрованные данные (через еще один буфер) в "Поток 4", который уже занимается выводом на экран. Можно еще больше "навернуть": для каждого графика и каждой выводимой таблицы - свой поток.
Как вариант - "Поток 2" занимается только фильтрацией полученных данных. А затем передает их другим потокам (3-й, 4-й, энный): одни - для записи в файл, другие - для отображения.
Если требуется какая-то обработка между получением и отображением, то: либо просто появляется промежуточный поток-обработчик между потоком-сборщиком и потоком-отображателем, либо обработка производится непосредственно в потоке-отображателе.
Для синхронизации работы потоков очень удобно использовать семафоры (CreateSemaphore и другие соответствующие функции). Если за время записи данных в файл появились новые данные, то ResumeThread просто не сработает - поток и так активен. Но если увеличишь счетчик соответствующего семафора, то по окончании записи поток-записыватель будет знать, что в буфере есть свежие данные. А сам этот поток (записыватель) уменьшает счетчик семафора, как только данные записаны в файл.
В принципе, как только данные получены, ты можешь (перед "укладыванием" их в буфер потоком-сборщиком) добавить время получения этих данных. Тогда еще менее критично становится скорость работы каждого конкретного потока. При записи (и последующем возможном просмотре записанных данных) и при отображении ты будешь видеть, когда реально были получены определенные величины.
Уф.... Устал писать уже