Russian Qt Forum

Qt => Общие вопросы => Тема начата: studert от Декабрь 08, 2008, 08:32



Название: Как запустить цикл на определенное время?
Отправлено: studert от Декабрь 08, 2008, 08:32
Здравствуйте. Задача следующая: необходимо в течение 50 мсек выполнять цикл по приемке пакетов с сети, пакеты идут со скоростью 95 мбит/сек, поэтому необходимо вовремя забирать их из буфера. Пытался воспользоваться таймером вот так, но похоже что-то не понял.
       
Код
C++ (Qt)
FrameTimer.setSingleShot(true);
FrameTimer.start(100);
while(FrameTimer.isActive()){
if(udpSocket.hasPendingDatagrams()){
... принимаем пакеты ...
}
Пробовал также создавать дополнительный слот, в котором устанавливал флаг выхода из цикла приема пакетов, и подключал его к сигналу таймера FrameTimer.timeout(), но тоже не помогло. Больше идей нет.. жду помощи.


Название: Re: Как запустить цикл на определенное время?
Отправлено: Rcus от Декабрь 08, 2008, 09:14
Чтобы таймеры работали необходимо обрабатывать события (обычно это делается автоматически при возврате в основной цикл).
Одно из решений это периодически вызывать QCoreApplication::processEvents(); в теле цикла.
Еще можно отойти от стратегии использования таймеров и использовать сигнал сокета readyRead()


Название: Re: Как запустить цикл на определенное время?
Отправлено: SASA от Декабрь 08, 2008, 09:43
50 мсек
Очень короткий промежуток....
Код:
QTime t;
t.start();
while (t.elapsed() <= 50)
{
///
}


Название: Re: Как запустить цикл на определенное время?
Отправлено: studert от Декабрь 08, 2008, 09:48
Спасибо, я про Qtime не знал. А 50 мсек это как раз время (даже с небольшим запасом) по отправке аппаратным модулем 480ти пакетов по 1Кбайту, так что хватит:)


Название: Re: Как запустить цикл на определенное время?
Отправлено: BRE от Декабрь 08, 2008, 10:26
Спасибо, я про Qtime не знал. А 50 мсек это как раз время (даже с небольшим запасом) по отправке аппаратным модулем 480ти пакетов по 1Кбайту, так что хватит:)
???
А если ядро займется чем-то более важным (по его мнению) и ты не успеешь приянть все пакеты?
Почему бы просто не принять 480 пакетов, зачем ограничивать время?


Название: Re: Как запустить цикл на определенное время?
Отправлено: studert от Декабрь 08, 2008, 11:09
Время отправки пакетов фиксированное (шлет плата с ПЛИС, которая не может отправлять дольше, ну никак), принять сразу все 480 не потеряв ни одного не всегда удается (в буфер сетевухи их мало влазит), поэтому считать принятые пакеты нельзя, а то получит 460 и из 480 отправленных, и что будет ждать вчерашний день? для этого и выход из цикла.


Название: Re: Как запустить цикл на определенное время?
Отправлено: BRE от Декабрь 08, 2008, 11:24
Хорошо, плата выплюнула сразу 480 пакетов, сколько получили, столько получили. А когда она в следующий раз будет делать отсылку? Может действительно, как предложил Rcus, асинхронно ждать доступных данных (сигнала readyRead)?


Название: Re: Как запустить цикл на определенное время?
Отправлено: studert от Декабрь 09, 2008, 11:03
Первоначально я так и сделал, слушал эфир, проверял что пришло, делал действие и опять слушал, при этом усложняется процедура определения момента времени для перерисовки полученных данных. Слушать эфир все время нет необходимости, железка шлет данные только по запросу, поэтому принимаю пакеты сразу после отправки запроса(предварительно очистив буфер), а после этого уже смотрю сколько чего пришло, при необходимости делаю запрос на повторную отправку потерянных данных и перерисовываю.


Название: Re: Как запустить цикл на определенное время?
Отправлено: BRE от Декабрь 09, 2008, 11:35
А не надо слушать все время. Послал запрос, когда пошли данные, получил сигнал readyRead, забрал что смог, обработал.


Название: Re: Как запустить цикл на определенное время?
Отправлено: studert от Декабрь 09, 2008, 13:27
Пока лучше получилось работать по таймауту, в дальнейшем может буду запрашивать данные меньшими порциями, чтобы они входили в аппаратный буфер сетевушки, тогда и с потерей проблем возникнуть не должно, а то сейчас все равно до 30-100 пакетов через раз теряется.


Название: Re: Как запустить цикл на определенное время?
Отправлено: Tonal от Декабрь 11, 2008, 09:03
Я бы пробовал отдельным потоком принимать.
Выставить ему приоритет побольше и слушать всё время.
Пришли данные - складываем в очередь и посылаем сигнал.
А в основном потоке (или другом рабочем) уже ловим сигнал и без спешки всё обрабатываем. :)