Blog. Just Blog

Использование мультимедийного таймера

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Интересная разновидность системных событий - высокоточный мультимедийный таймер. Гарантированный интервал срабатывания мультимедийных таймеров - около 10 миллисекунд против 50 миллисекунд обычных таймеров, устанавливаемых при помощи функции SetTimer. Кроме того, мультимедийные таймеры позволяют использовать обработчики, которые будут срабатывать в нужные интервалы, тогда как сообщения WM_TIMER от обычных таймеров идут через общую очередь. Если главный поток подвис, заснул или продолжительное время реагирует на какое-нибудь тяжелое сообщение, то таймеру придется ожидать, пока обработчик дойдет до него. Таким образом, добиться предсказуемой периодичности таймера будет очень сложно. Мультимедийные таймеры выполняются в собственном потоке, поэтому лишены перечисленных недостатков.

Слова словами, но давайте проверим это на практике. Для этого в простом оконном приложении установим обычный таймер на интервал 1 миллисекунду, вместе с этим создадим мультимедийный таймер с таким же интервалом срабатывания. При каждом срабатывании каждого из этих таймеров будет увеличен соответствующий счетчик. По истечении определенного времени, например, 5 секунд, сравним результаты.

Обработчик окна будет выглядеть примерно так. Для удобства я оставил только минимально необходимый код.
  1.         cmp     [msg],WM_INITDIALOG
  2.         je      wminitdialog
  3.         cmp     [msg],WM_TIMER
  4.         je      wmtimer
  5.         ...
  6.         ...
  7. wminitdialog:
  8.         ; Обнулить счетчики
  9.         mov     [dCntTim],0
  10.         mov     [dCntMM],0
  11.  
  12.         ; Получить начальное время
  13.         invoke  GetTickCount
  14.         mov     [dTime],eax
  15.  
  16.         ; Установить обычный таймер на интервал 1 мс
  17.         invoke  SetTimer,[hwnddlg],1,1,NULL
  18.  
  19.         ; Установить мультимедийный таймер на интервал 1 мс
  20.         TIME_PERIODIC = 0x0001
  21.         invoke  timeSetEvent,1,1,TimeProc,777,TIME_PERIODIC
  22.  
  23.         ...
  24.         ...
  25. wmtimer:
  26.         ; Увеличить счетчик по событию WM_TIMER
  27.         inc     [dCntTim]
  28.  
  29.         ; Прошло 5 секунд?
  30.         invoke  GetTickCount
  31.         sub     eax,[dTime]
  32.         cmp     eax,5000
  33.         jb      processed
  34.         jmp     wmclose
  35.  
  36. wmclose:
  37.         ; Удалить оба счетчика
  38.         invoke  KillTimer,[hwnddlg],1
  39.         invoke  timeKillEvent,[hTimer]
При инициализации окна устанавливается обычный и мультимедийный таймеры, при получении сообщения WM_TIMER увеличиваем обычный счетчик, а в функции-обработчике высокоточного таймера увеличиваем мультимедийный счетчик.
  1. ;-----------------------------------------------------------
  2. ; Обработчик высокоточного таймера
  3. ;-----------------------------------------------------------
  4. proc TimeProc uTimerID:DWORD,uMsg:DWORD,dwUser:DWORD,dw1:DWORD,dw2:DWORD
  5.         ; Увеличить счетчик по системному событию
  6.         inc     [dCntMM]
  7.         ret
  8. endp
Ну и момент истины. По результатам тестирования выяснилось, что за 5 секунд обычный таймер вызывается всего около 320 раз, тогда как обработчик мультимедийного таймера вызывается четко не менее 5000 раз. Что и требовалось доказать.

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

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Multimedia.Timer.Demo.zip (2,432 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 1301 | Комментариев: 4

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Виталий (09.09.2022 в 18:48):
Очень благодарен за статью! 1к% это то, что мне сейчас нужно.
ManHunter (03.09.2020 в 22:05):
Не статья, а опечатка на опечатке, уже сколько исправил. Вроде трезвый набирал :(
Владимир (03.09.2020 в 21:47):
"вытокоточного" очапутка в тексте.
Сорри. С телефона, не могу Ctrl+Enter
zdm (26.08.2020 в 07:21):
Спасибо. Очень полезно.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0054 сек.) / Память: 4.5 Mb
Наверх