Russian Qt Forum
Ноябрь 23, 2024, 05:03 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Аналог виндового мультимедиа таймера в Qt  (Прочитано 18574 раз)
Alex_C
Гость
« : Июнь 21, 2012, 20:17 »

Как известно , в винде есть так называемый мультимедиа таймер, отличие от простого таймера в том, что он выполняется в четко заданные промежутки времени , а не когда освободится система, как в обычном таймере, и в том, что вызываемая в нем callback-функция вызывается в отдельном потоке. Вопрос - понятно что под Qt можно использовать непосредственно сам мультимедиа таймер, но но это получается платформазависимый код. А как реализовать мультимедиа таймер средствами Qt?
Записан
Bepec
Гость
« Ответ #1 : Июнь 21, 2012, 20:50 »

Кхм. Задам глупый вопрос насчёт мультимедиа таймера:

То есть вы хотите сказать, что на мультимедиа драйвер не распространяется погрешность Windows в подсчёте времени? Которая заявлена как 15+-(частота кварца компа) мс?

По теме - очередь сообщений ООООЧень быстрая. Задержки в ней не замечается и не заметите, разве что слипать будете поток(или спамить).

К тому же чего вы хотите добиться? Мгновенной передачи сообщения? Так возьмите и создаёте отдельный объект в потоке и спрячьте его. Пусть и крутит таймер.

Записан
Alex_C
Гость
« Ответ #2 : Июнь 21, 2012, 21:57 »

Да, я знаю, что для программиста, впервые столкнувшегося со столь специфическим таймером, это как откровение Улыбающийся
Точность этого таймера по официальной информации не хуже 1мс. Да-да, везде пишут, что точность Виндовс - 15 мс. Но по ходу это не программый, а аппаратный таймер, входящий в состав материнской платы (не уверен - точной инфы по этому поводу не нашел)
Основная особенность этого таймера - при возникновении события он блокирует выполнение всех процессов в системе, и выполняет callback ф-цию. По этому никакими тредами его заменить нельзя - в них погрешность действительно 15 мс.
Зачем он нужен? Как видно из названия - для мультимедиа Улыбающийся
У меня же он используется для управления внешним девайсом по ком-порту (выставлением высокого/низкого уровня по RTS-DTR). При использовании виндового таймера, тредов происходит сбой посылок, что не дает возможности управлять устройством.
Записан
Bepec
Гость
« Ответ #3 : Июнь 21, 2012, 22:03 »

Я тебе по секрету сообщу ) Это такой же таймер, базирующийся на кварце Веселый Просто вместо постановки события в очередь, он вызывает исполнение события Веселый

postEvent sendEvent что нить говорят?Улыбающийся

Погрешность у него такая же ) +-15мс.

И опять по секрету скажу - Qt использует его, насколько я понимаю Веселый Обычный QTimer вызывает платформозависимый код, который в свою очередь вызывает что? Один из таймеров виндовс.
В моём проекте достигается точность в 1-2мс, с периодическими прорывами в 13-14 мс. И это норма.

PS Прочитал 3 статьи, перерыл исходники Qt Веселый
Записан
Alex_C
Гость
« Ответ #4 : Июнь 21, 2012, 22:19 »

Да прийдется смотреть исходники QTimer. Какой таймер используется там.
На счет postEvent sendEvent все понятно... Но добиться эффекта без использования мультимедиа таймера под виндой с заданной точностью не получается.
Записан
Bepec
Гость
« Ответ #5 : Июнь 21, 2012, 22:33 »

значит используй его Веселый Qt в любом случае использует платформозависимый код Улыбающийся
Записан
Alex_C
Гость
« Ответ #6 : Июнь 21, 2012, 22:43 »

К сожалению под виндой QTimer использует стандартный виндовый таймер, что не дает нужной точности.
Прийдется писать свой аналог QTimer, где под виндой использовать мультимедиа таймер, а под Линуксом - уже нашел - есть аналог мультимедийного таймера. В принципе код получится простой Улыбающийся

P.S. Хорошо что под Mac пока делать не надо!
Записан
Alex_C
Гость
« Ответ #7 : Июнь 21, 2012, 22:50 »

Ура-ура!
Нашел ответ на свой вопрос! Все же не устаю удивляться, как все продуманно в Qt!
Оказывается, при задании интервала менее 20 мс, под виндой используется мультимедиа таймер, при большем интервале - стандартный виндовый. Во как!!!

http://www.qtcentre.org/threads/27328-QTimer-resolution
Записан
Bepec
Гость
« Ответ #8 : Июнь 21, 2012, 23:10 »

Я ж и говорю. точность 1-2 мс у мну в проекте ) всё круто Веселый
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #9 : Июнь 25, 2012, 13:48 »

а под Линуксом - уже нашел - есть аналог мультимедийного таймера.

Скинь ссылку
Записан
Bepec
Гость
« Ответ #10 : Июнь 25, 2012, 13:52 »

Alex Custov - Есть такое подозрение, что тролли и об линуксовском таймере подумали. Во всяком случае на линуксе моя программа выдаёт ту же погрешность 1-2 мс. Меньше уже просто нереально Веселый
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #11 : Июнь 25, 2012, 23:48 »

Оказывается, при задании интервала менее 20 мс, под виндой используется мультимедиа таймер, при большем интервале - стандартный виндовый. Во как!!!
http://www.qtcentre.org/threads/27328-QTimer-resolution
Не очень убедительно. Если поглазеть на исходники, никакого multimedia timer не используется. Используется процессорный Performance Counter, но это уже совсем другая история. Забудьте навсегда словосочетания Windows и 1 мс. Любой из таймеров в виндовс в общем случае гарантированно не будет срабатывать ни за какой промежуток времени - ОС не рассчитана реалтайм применение. Если процессор будет загружен чем-то с его точки зрения более важным, Ваш таймер может не сработать никогда, независимо от способа его реализации, будь то GetTickCount (стандартный таймер Windows), timeGetTime (multimedia timer) или QueryPerformanceFrequency (Performance Counter). Про Линукс говорить не буду - нет большого опыта программирования под него, но что-то мне подсказывает, что там ситуация похожая.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #12 : Июнь 26, 2012, 01:14 »

Во всяком случае на линуксе моя программа выдаёт ту же погрешность 1-2 мс. Меньше уже просто нереально Веселый

Скинь минимальный тестовый пример.
Записан
Bepec
Гость
« Ответ #13 : Июнь 26, 2012, 07:19 »

Увы, не получится. Там практически всё построено на корпоративных классах Улыбающийся За разглашение - наказывается лишением свободы на срок от трех до семи лет. Веселый

Что могу сказать без примера:

Хокс во первых прав (погрешность та же в 1-15 мс остаётся), это уже виндосовские заморочки.
Во вторых погрешность почему-то отрабатывает раз в какой-то промежуток времени.
Т.е. к примеру 15 сигналов с перерывом в 1-2 мс (), далее неизвестный тормоз на 2-15 мс и продолжаемс..

PS Хотя у меня один знакомый пытался собрать модель для тактового подсчёта, но не смог Улыбающийся
« Последнее редактирование: Июнь 26, 2012, 09:31 от Bepec » Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #14 : Июнь 26, 2012, 08:46 »

Во вторых погрешность почему-то отрабатывает раз в какой-то промежуток времени.
Т.е. к примеру 15 сигналов с перерывом в 1-2 мс (), далее неизвестный тормоз на 2-15 мс и продолжаемс..
Так и я об этом же. Установите интервал таймера, например, в 10 мс, и посчитайте количество срабатываний за продолжительный промежуток, например за 10 мин, и увидите, что если в это время комп занимается обычными делами (переключает задачи, качает файлы и т.п.), то:
1. Количество срабатываний не будет равно 10 * 60 * 1000 / 10.
2. Интервал между срабатываниями будет самый разный, вплоть до сотен милисекунд.
Ни один из видов системных таймеров не даст на ОС, не имеющей realtime подсистемы стабильных срабатываний с малыми интервалами. Как один из вариантов выхода из этой ситуации - учитывать время срабатывания таймера и вызывать обработчик таймера столько раз, сколько "лишних" тиков уже накопилось. Например, если нужен интервал в 10 мс, а с момента последнего срабатывания прошло 22 мс, то вызывать обработчик 2 раза и запомнить, что 2 мс ещё осталось и их тоже надо учесть при следующем вызове.
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.056 секунд. Запросов: 22.