-
Есть задача: получение телеметрии от оборудования по ком- порту. Причем как можно чаще. Для этой цели я использую отлельный поток и в цикле while not Terminated... <посылаю комманду оборудованию на получение данных>
От ком-порта я получаю данные и должен их обработать. Вопрос: как лучше реализовать, чтобы пока полученные данные от ком-порта не обработались, следующая комманда позылки запроса телеметрии не выполнялась? Я делаю так: в потоке
while not Terminated do
begin
DataGet := False;
<посылаю комманду оборудованию на получение данных>
while not DataGet do
Application.ProcessMessages;
end;
В основной программе: Ф-ция, вызываемая при приеме данных из ком-порта:
<проверяем данные на валидность, и если все верно> then
DataGet := True
else
DataGet := False;
Идея понятна. Но что то меня терзают смутные сомнения в ее правильности. :)
-
если как можно чаще, то вообще-то не надо ждать обработки данных. пусть они постоянно получаются в потоке и накапливаются. а основной поток занимается обработкой. в противном случае смысла в потоках как-то маловато становится. и еще: > <проверяем данные на валидность, и если все верно> then > DataGet := True > else > DataGet := False;
проще и красивше: DataGet := <проверяем данные на валидность>;
-
> если как можно чаще, то вообще-то не надо ждать обработки > данных.
Я тоже над этим думал, но вот в чем проблема: телеметрия считывается не с одной комманды, а в зависимости от оборудования от 1 до ... комманд (имеется ввиду посылка комманды оборудованию на ком порт). Хочется создать универсальную программу для считывания телеметрии с датчиков от разных фирм, просто указывая, с какогй марки датчика считываем данные. Я не смог придумать сносного алгоритма, как таким образом считывать данные? Вот мы постоянно посылаем комманду на получение телеметрии. Постоянно приходят с ком-потра данные. Мы их заносив в буфер - тут все понятно. Непонятно - как декодировать. Потому как есть датчика, которые имея несколько комманд получения телеметрии, в ответ шлют определенное кол-во байт информации. Вот и вся валидность...
-
> Непонятно - как декодировать. > Потому как есть датчика, которые имея несколько комманд > получения телеметрии, в ответ шлют определенное кол-во байт > информации. Вот и вся валидность...
это должно быть в даташите на датчик.
-
в этом же потоке и обрабатывай, в основной поток только результат отдавай... Application.ProcessMessages; - в потоке ерунда
Alex_C (02.02.11 18:15) [2] просто указывая, с какогй марки датчика считываем данные дык жестко не прописывай строку запроса, а формируй ее на основе настроечных данных, ответ парсь также по настройкам
-
> в этом же потоке и обрабатывай, в основной поток только > результат отдавай...
Вот эта мысля у меня уже давно в голове бродит: но как? Данные с ком порта я получаю в основном потоке - по событию прихода данных. Считывать их в самом потоке после посылки данных в порт? Т.е. алгоритм потока должен выглядеть так:
while True do
begin
SendCommandToComPort(<Послали комманду запроса>);
while <пока не вышел таймаут ожидания> do
begin
if WaitingData > 0 then begin
ReadBytes(<Считываем данные>);
<Если данные валидны> then
begin
DecodeData; <- Здесь мы декодированные данные отдаем программе
Break;
end;
end;
end;
end;
Как такой вариант?
-
> Slym © (03.02.11 07:30) [4] > > в этом же потоке и обрабатывай, в основной поток только > результат отдавай...
и получаем хрень, если время обработки превысит тз "как можно чаще". и вообще, смысл тогда? можно все в основном сделать, фигли там остается-то на готовые результаты.
-
KilkennyCat © (03.02.11 11:12) [6] 1. Девайс шлет данные по запросу, т.е. нет непрерывного потока данных для обработки которого нужна машина реального времени 2. Зачем просить еще когда предыдущий кусок не проглотил... 3. Alex_C (03.02.11 10:18) [5] пойдет
-
> Slym © (03.02.11 11:27) [7]
1. в этом случае да, но в тз висит "как можно чаще". т.е. приближаемся к непрерывному потоку. 2. опять же, исходя из тз. может, датчик меряет температуру, и нужна полная картина в динамике, тогда, проглотил или нет, данные нужно получить.
в противном случае, повторюсь, нет нужды в потоке. отправили запрос, получили данные, обработали, и заново... какой смысл в потоке?
-
KilkennyCat © (03.02.11 12:34) [8] какой смысл в потоке? не подвешивать гуй
-
> Slym © (03.02.11 12:41) [9]
согласен, единственная причина. и только при условии, что пока ждем данные, пока обрабатываем, есть чем заняться еще.
я когда-то что-то подобное делал. причем, в извращенной форме - я знал, какие данные от датчиков должны быть, как обработать и как вывести. но совершенно не знал формата выхода с датчика, и ваще какие датчики заказчик будет ставить.
чтобы упростить работу себе, я тупо сделал главную прогу, которая тупо считывала с файла данные, обрабатывала и т.д. Потом смотрела снова файл... так я определил для себя промежуточный формат данных. по получении датчика, я написал небольшого резидента, который опрашивал датчик и скидывал в тот самый файл... в уже нужном мне формате. переход на любой другой датчик не вызывал проблем никаких, не требовал пересбора всего проекта.
-
1. ProcessMessages не нужно вызывать не в основном потоке 2. Можно предложить вариант с двумя дополнительными потоками: один занимается опросом датчиков и получением ответов, пересылает ответы второму доп. потоку, тот их обрабатывает и пересылает результат в главный поток. Так, как мне кажется, будет наибольшая скорость обработки и удобство чтения кода (разделение кода, отвечающего за разные вещи, между разными потоками (классами))
-
> в этом же потоке и обрабатывай, в основной поток только > результат отдавай...
В общем сегодня реализовал этот вариант. Результат - просто класс :) Алгоритм - как я описывал выше (естественно он получился куда как сложнее, но идея ясна.) Совет для тех, у кого такая же задача как и у меня - делать так, как предложено. По ходу это единственно верный путь. Перепробовал и остальные - результат куда как хуже.
-
> Можно предложить вариант с двумя дополнительными потоками: > один занимается опросом датчиков и получением ответов, > пересылает ответы второму доп. потоку, тот их обрабатывает > и пересылает результат в главный поток.
Не будет. Сам посуди - нам все равно прийдется эти два потока сихронизировать, чтоб они друг от друга не "убежали". Это и лишнии проблемы, и скорости нет. А с одним потоком скорость практически получается в режиме реально времени. Сегодня опробовал!
-
большая ошибка. не будет тут реального времени, никоим образом, когда и получение и обработка в одном потоке. более того, есть риск потери информации.
> По ходу это единственно верный путь. Перепробовал и остальные > - результат куда как хуже.
просто не умеешь.
> Сам посуди - нам все равно прийдется эти два потока сихронизировать, > чтоб они друг от друга не "убежали". Это и лишнии проблемы, > и скорости нет.
не понимаешь идеологии. Хотя GreyWolf предложил классический общий вариант, именно с такого и надо было начинать, усложнение или упрощение уже зависит от тз.
-
> Alex_C (03.02.11 21:44) [13]
Будет:) Передача сообщения другому потоку делается асинхронно. То есть примерно так: В доп. потоке 1, работающем с COM портом:
while true do
begin
1.1. Опросить_следующий_нуждающийся_в_опросе_датчик
1.2. Выделить память под структуру, содержащую результат опроса, и скопировать туда данные, полученные в буфер в п.1.1
1.3. Асинхронно отправить укзатель на эту структуру в доп. поток 2
end;
В доп. потоке 2, обрабатывающем данные опроса
while true do
begin
2.1. Получить указатель на следующие в очереди данные, отправленные в 1.3
2.2. Обработать эти данные
2.3. Асинхронно отправить результат в главный поток
2.4 Освободить память, выделенную в 1.2
end;
Тогда если есть четыре датчика A, B, C, D, у которых период опроса у каждого - 50 мс, а период обработки - 10, 20, 100, 60 мс соответственно, то результирующий период опроса будет составлять максимум из периода опроса и периода обработки, в этом случае - Max(200, 190) = 200 мс. Если это все делать в одном потоке и не заморачиваться на асинхронных событиях приема и передачи данных, (и соотв. разбивки алгоритма обработки на машину состояний с периодическим выходом из этого алгоритма для проверки возникновения событиий приема и передачи данных), то результирующий период опроса будет равен _сумме_ периодов опроса и обработки, т.е. в этом случае 390 мс. А учитывая современный тренд в сторону все большего кол-ва ядер, можно и дальше оптимизировать под несколько потоков обработки данных.
-
> > Alex_C (02.02.11 17:35) > > Есть задача: получение телеметрии от оборудования по ком- > порту. Причем как можно чаще. Для этой цели я использую > отлельный поток и в цикле > > > while not Terminated... > <посылаю комманду оборудованию на получение данных>
Бред. В данной задаче пригоден только асинхронный способ общения с внешним железом. А значит никакие доппотоки не нужны и даже мешают. Хотя, чисто теоретически, если грамотно разделить "общение" и "анализ", то можно достичь максимально возможной частоты получения информации от внешнего устройства.
-
> Германн © (04.02.11 06:44) [16]
Бред.
> В данной задаче пригоден только асинхронный способ общения > с внешним железом. А значит никакие доппотоки не нужны и > даже мешают.
Бред - это когда бред пишешь без аргументов. Чем тебе мешает доп. поток? Можно ли организовать работу в основном потоке с COM портом? Да можно, , но намного ли это проще? Выигрыш от этого один - нет необходимости в синхронизации между потоками. А хорошо ли это масштабируется? Что будет если портов будет больше чем 1,2, 3 или 10 или еще больше? Рекомендую почитать Рихтер Дж., Кларк Д.Д. - "Программирование серверных приложений" Главу 2 "Ввод-вывод и межпотоковое взаимодействие "
-
Удалено модератором
-
Удалено модератором
-
Чем тебе мешает доп. поток?
тем что если чтение данных будет асинхронное, то в доппотоке придется крутить тупейший цикел ожидания, который ничего не будет делать.
-
> если чтение данных будет асинхронное
а это как?
-
кгшзх © (20.01.16 13:51) [20]
На дату ветки посмотри :)
|