Родились сегодня:
Rosiam


Лидеры рейтинга

ID: 226425

Konstantin Shvetski

Модератор

723

Россия, Северодвинск


ID: 259041

Алексеев Владимир Николаевич

Мастер-Эксперт

326

Россия, пос. Теплоозёрск, ЕАО


ID: 401284

Михаил Александров

Академик

279

Россия, Санкт-Петербург


ID: 325460

CradleA

Мастер-Эксперт

211

Беларусь, Минск


ID: 400815

alexleonsm

6-й класс

130


ID: 400669

epimkin

Профессионал

120


ID: 401888

puporev

Профессор

111

Россия, Пермский край


8.8.15

09.05.2021

JS: 2.8.21
CSS: 4.5.5
jQuery: 3.6.0
DataForLocalStorage: 2021-05-11 18:46:03-standard


Создание программ на языках Pascal, Delphi и Lazarus.

Администратор раздела: Зенченко Константин Николаевич (Старший модератор)

Консультация онлайн # 159463

Раздел: Pascal / Delphi / Lazarus
Автор вопроса: Geb2003
Дата: 03.02.2009, 08:11 Консультация закрыта
Поступило ответов: 0

Здравствуйте Уважаемые Эксперты!
Подскажите как в Дельфи сделать задержку меньше 1 мсек (это минимум по стандартному таймеру), при этом программа не должна зависать на время задержки, то есть реагировать на мышку, клавиатуру, выполнять какую-нибудь другую процедуру.
За ранее благодарю за ответ.

Ответов пока не поступило

Мини-форум консультации # 159463
Monah

1

= общий =    03.02.2009, 09:03

Теоритически можно использовать переменную Time сравнивая разницу между старым значением и новым. Для получения секунд необходимо умножить на (24*60*60) = 86400
Для того чтоб программа не висла, необходимо использовать application.processmesage - метод обработает все поступившие сообщения.
Но мне кажется столь короткие промежутки времени, с хорошей точностью, отловить нереально. Опишите задачу полнее, возможно решение есть.

q_id

Вадим Исаев ака sir Henry

Мастер-Эксперт

ID: 425

2

= общий =    03.02.2009, 09:27

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

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

q_id

Хватов Сергей

Академик

ID: 20764

3

= общий =    03.02.2009, 10:46

Задержка без зависания - это работа с прерываниями. Увеличить частоту системного таймера вряд ли можно безнаказанно. Но можно использовать периодические прерывания от rtc (если конечно его не использует сама ОС. Linux не использует).
Только это к delphi имеет весьма опосредованное отношение.

PGM

4

= общий =    04.02.2009, 10:46

Есть способ как засечь более мелкие промежутки времени чем 1 мсек (через тики процессора (команда ассемблера rdtsc) и знание частоты CPU), но таким образом точную задержку не организовать. Хотя попытаться организовать поток с постоянным анализом тиков и генерацией событий по более мелким промежуткам времени можно, но скорее всего такой поток будет сильно грузить процессор (точнее - одно ядро, если очень надо можно и пожертвовать этим). Но действительно ли надо?

По поводу GetTickCount : [MSDN] GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer. Т.е. меньше мсек с помощью ее все равно не получить.

q_id

Вадим Исаев ака sir Henry

Мастер-Эксперт

ID: 425

5

= общий =    04.02.2009, 13:32

PavelGM
Многое будет зависеть от функции, которая выполняется при срабатывании таймера. Системный таймер, если не успевает выполнить функцуию в течении своей разрешающей способности (примерно 15 мс или около того), будет устойчиво накапливать ошибку, если функция каждый раз не будет создавать для себя отдельный поток. Точнее, функция должна быть уже сама по себе в отдельном потоке.
Мультимедиатаймер, судя по MSDN, вызывает свою callback-функцию уже в отдельном потоке, но и здесь, как ни странно, бывают ошибки периода при разрешении менее чем в 2..3 мс.
А вот с GetTickCount можно задать создание нового потока при каждом наступлении новой милисекунды, если старый отдельный поток не успел отработать и, тем самым, гарантировать разрешающую способность в 1 мс. Впрочем, тут нужны эксперименты. smile
Таким образом всё упирается в решаемую функцией таймера задачи. smile

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

PGM

6

= общий =    05.02.2009, 00:47

To sir Henry
В вопросе спрашивалось можно ли "сделать задержку меньше 1 мсек". Замечание по поводу GetTickCount касается именно этого. Cобственно единственный известный мне метод как можно это попытаться (!) сделать это - использовать команду rdtsc.

Виктор Пырлик

7

= общий =    08.02.2009, 13:36

Всё просто, если у Вас не ОС реального времени, (а вопрос по Delphi, следовательно у Вас Windows – это не операционка реального времени), то Вы не теоретически не практически не сможете реализовать такой опрос/задержку. Максимум что Вы сможете гарантировать на 100% - это 0,5 секунды. Всё что ниже (например, 100 мсек) – это на усмотрение ОС, т.е. может сейчас и будет выдержан такой период, но в следующий момент никто Вам не даст гарантии что задержка не составит 800 мсек.. Даже великий Бил Гейтс тут не поможет.
Эта проблема довольно распространена, и весьма часты заключения и даже «гарантии» знатных фирм о времени актуальности 100 и менее мсек – для ОС Windows это бред.

По поводу задержки – «что бы не висло».. с таким тайменгом Вы при всем желании не заметите «висение», а вот если у Вас это в цикле крутится, то как верно заметили – открывайте новый поток, и в нем реализуйте опрос/задержки. Иначе никак.

To ALL:
Не забываем, что работает принцип карусели, с четко определенным квантом времени на контекст процессора и на переключение между контекстами, к тому же, переключение не линейное а в зависимости от приоритета, откуда ясно что уровень ядра имеет больший приоритет. Следовательно, когда дойдет очередь до вашего процесса – никто не скажет. Кванты времени на контекст и переключение между ними – тайна MS. Но даже, зная это, приоритетность задач (очередь приоритетов) не даст возможности провести точный расчет и как следствие дать однозначную гарантию. Любой вызов любой функции – есть уже задача переключения, следовательно, использование GetTickCount – простой вызов получения информации по «тикам».. т.е. «сколько их на момент получения ресурса функцией GetTickCount».. :))))

Использование ASM в системах NT весьма не так просто, особо, человеку, который задаёт такой вопрос. Да й как Вы это представляете??? Отнять у ОС её время????

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Лучшие эксперты раздела

puporev

Профессор

Рейтинг: 111

Зенченко Константин Николаевич

Старший модератор

Рейтинг: 73

Степанов Иван /REDDS

4-й класс

Рейтинг: 1

Лысков Игорь Витальевич

Мастер-Эксперт

Рейтинг: 0

Асмик Гаряка

Советник

Рейтинг: 0

Орловский Дмитрий

Мастер-Эксперт

Рейтинг: 0