LINUX.ORG.RU

[Qt 4.6.0] Странная работа таймера


0

0

В программе реализован сбор данных с определенной частотой.
В основном потоке по таймеру (QTimer) с частотой 25 Гц перерисовывается графика.
В отдельном потоке собираются данные с частотой задаваемой в программе. Таймер запускается через QObject::startTimer(1000.0/<Частота>), сбор происходит в timerEvent(). По первому впечатлению все работает, но когда начали пробовать сбор на разных частотах (от 1 до 100 Гц) выяснилось, что в зависимости от частоты сбор происходит то медленнее, то быстрее, то как положено. При том на 100 Гц как раз все в порядке, проблемы как раз на более низких частотах.
Возможно дело в конкретной версии Qt.

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

>При том на 100 Гц как раз все в порядке, проблемы как раз на более низких частотах.

Оставь на пару дней - хрен тебе будет, а не 100Гц. Особенно на стандартном ядре без RT патчей.

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

golodranez ★★★★ ()

Возможно, таймер, используемый для сбора данных, кидает события в тот же event loop, что используется для GUI, обработка которого в свою очередь тормозит из-за постоянной отрисовки графики. Минимальный код покажи.

mannaz ()
Ответ на: комментарий от mannaz

> Минимальный код покажи

Интересует прежде всего создание основных объектов: потока для сбора данных, его таймеров и т.п.

mannaz ()
Ответ на: комментарий от mannaz

LScopeWindow::LScopeWindow() { ... thread = new QThread(this); pDevice = new Device; pDevice->moveToThread(thread); connect(thread,SIGNAL(started()),pDevice,SLOT(startAdc())); ... }

Device наследник QObject

void Device::startAdc() { m_id = startTimer(1000.0/dev140.freq); }

void Device::timerEvent(QTimerEvent *event) { <Сбор данных> }

TarANtuL ()
Ответ на: комментарий от TarANtuL

LScopeWindow::LScopeWindow() {
...
thread = new QThread(this);
pDevice = new Device;
pDevice->moveToThread(thread);
connect(thread,SIGNAL(started()),pDevice,SLOT(startAdc()));
...
}

Device наследник QObject

void Device::startAdc()
{
m_id = startTimer(1000.0/dev140.freq);
}

void Device::timerEvent(QTimerEvent *event)
{
<Сбор данных>
}

TarANtuL ()

QTimer не гарантирует точности, цитата из доков:

Accuracy and Timer Resolution

Timers will never time out earlier than the specified timeout value and they are not guaranteed to time out at the exact value specified. In many situations, they may time out late by a period of time that depends on the accuracy of the system timers.

The accuracy of timers depends on the underlying operating system and hardware. Most platforms support a resolution of 1 millisecond, though the accuracy of the timer will not equal this resolution in many real-world situations.

If Qt is unable to deliver the requested number of timer clicks, it will silently discard some.

tzukko ()
Ответ на: комментарий от tzukko

Именно по этому задал два вопроса. Но смущает что при 100 Гц опроса он точнее чем, скажем, при 20 Гц.

Иными словами, ставлю на запись с частотой 20 Гц (50 мс) число точек, чтобы он закончил через 20 мин, а запись заканчивается через 24. Если проделать это для 100 Гц (10 мс), то запись закончится как раз через 20 мин.

TarANtuL ()
Ответ на: комментарий от TarANtuL

Похоже, что события с интервалом в 50 мс на вашей системе все равно иногда теряются, что в общем ощущается сильнее, чем потеря части событий с интервалом 10 мс.

mannaz ()
Ответ на: комментарий от mannaz

Проверил, события не теряются, таймер работает стабильно но с другой задержкой. Ставил 50 мс, а в записанном файле 62 мс.

TarANtuL ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.