Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подскажите как сделать маленькую задержку 
:(
    Опции темы
SKN
Дата 24.10.2004, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 23.10.2004

Репутация: нет
Всего: нет



Просто Sleep не проходит, надо стопорить прогамму на 1мс, с ошибкой не более 50мкс. Подозреваю, что точность установки Sleep >10мс происходит из-за многопоточности виндов, где-то читал, что время переключения между потоками - 1мс. Если этот так, то вопрос ставится так: как сделать мою программу на какое-то время единственным потоком, чтобы никакие опросы CDROM'а , сети, дисководов и пр. мне не мешали. Спасибо.

PM MAIL   Вверх
cardinal
Дата 24.10.2004, 02:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

Репутация: 2
Всего: 99



Читай тут
ttp://www.sources.ru/NonCGI/Forum2/HTML/001250.html
и тут
http://bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=4&m=82812


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
bel_nikita
Дата 24.10.2004, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



SKN
Sleep - переключает треды. Можно просто использовать запись или чтение в какой-нить порт, но винда по-моиму это запрещает. Надо на уровень ядра спускаться.

Ипользовать для задержки запись в какой-нить порт, и замерять при помощи QueryPerformanceFrequency и QueryPerformanceCounter

Это сообщение отредактировал(а) bel_nikita - 24.10.2004, 21:53


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Mad
Дата 24.10.2004, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

Репутация: 7
Всего: 19



SKN
Посмотри в MSDNе описание критических секций.


--------------------
user posted image
PM MAIL   Вверх
p0s0l
Дата 24.10.2004, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 2
Всего: 112



Mad, я думал, что критические секции - для синхронизации потоков...
Как тут их можно применить ?

SKN,
1) Можно остановить в системе все потоки:
CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD...), каждый поток остановить (SuspendThread). Чтобы останавливать системные потоки, надо получить привилегию "SeDebugPrivilege"...
Либо:
Просто поставить приоритет текущего процесса/потока = Real-Time / Time-Critical (SetPriorityClass / SetThreadPriority)
(эффект от обоих способов почти одинаковый)

2) Использовать QueryPerformanceFrequency и QueryPerformanceCounter.
Я проверял на двух компах, на одном частота таймера = 3,58 МГц, на другом = 2,1 МГц. Соответственно, можешь посчитать, с какой точностью можно отсчитывать время (подели 1 на частоту)...
Либо:
Более точные измерения - это через RDTSC. Частота проца в сотни раз больше частоты таймера. Хотя эта точность уже будет излишней... Главная проблема - переключения задач, из-за которых для потока получаются "провалы" во времени...

Если сделать 1 и 2, то будет еще одна бяда: всё "встанет": замерзнет звук и экран, клава и мышь заглохнут и т.д, пока твой поток будет в цикле мерять время...
Таким способом я добился на своём компе:
среднее отклонение 50 мкс (как раз), но встречаются "заскоки" - 210 мкс (возникающие из-за переключения задач)...


--------------------
С уважением, г-н Посол.
PM   Вверх
SKN
Дата 25.10.2004, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 23.10.2004

Репутация: нет
Всего: нет



Спасибо всем за ответы, завтра попробую
PM MAIL   Вверх
Adil'
Дата 25.10.2004, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 26.8.2004
Где: Питер

Репутация: 6
Всего: 15



Цитата(SKN @ 24.10.2004, 00:33)

Просто Sleep не проходит, надо стопорить прогамму на 1мс, с ошибкой не более 50мкс
Может и зря я это говорю, но утерпеть не могу: когда решение проблемы выглядит очень уж сложным, то может все-таки пересмотреть саму постановку задачи? Что-то мне даже в голову не приходит - где может потребоваться такая критичность по времени - очень часто можно обойтись более простыми способами.

SKN, распиши проблему по-подробнее, может в самом деле можно ее решить как то более тривиально?


--------------------
Удачи
PM MAIL WWW   Вверх
Sep.
Дата 26.4.2005, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



Цитата
2) Использовать QueryPerformanceFrequency и QueryPerformanceCounter.
Я проверял на двух компах, на одном частота таймера = 3,58 МГц, на другом = 2,1 МГц. Соответственно, можешь посчитать, с какой точностью можно отсчитывать время (подели 1 на частоту)...

а где они находятся? какой хидер подключить надо в Билдере 6?
Цитата
распиши проблему по-подробнее, может в самом деле можно ее решить как то более тривиально?

у меня сходная проблема: программа управляем шаговым двигателем. Так даже 1мс не добится. Если делаю что то типа
Код
  TDateTime dtStart = Now();
  for(int i=0;i<=100;i++){
    Sleep(1);
  }
  TDateTime dtEnd = Now();
  dtStart=dtStart-dtEnd;
  DecodeTime(dtStart, Hour, Min, Sec, MSec);
  ShowMessage("Min:" + IntToStr(Min) + " sec:" + IntToStr(Sec) + ":" + IntToStr(MSec));

то получается что sleep(1) выполняется 15мс! То же самое и с Now() и clock()
Подскажите как хотя бы 1мс получить в билдере?
Спасибо.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
Дрон
Дата 26.4.2005, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 93



Sep.
Не ту ты операционку выбрал, чтобы двигателями управлять...

Цитата(Sep @ 26.4.2005, 01:58)
а где они находятся? какой хидер подключить надо в Билдере 6?

windows.h попробуй



--------------------
Да. Именно так.
PM   Вверх
zhgutov
Дата 26.4.2005, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 14.12.2004

Репутация: 1
Всего: 2



Можно попробовать что-нить типа этого:
Код

// timer.h
#ifndef TIMER_HPP
#define TIMER_HPP

#include <tchar.h>
#include <windows.h>
#include <windowsx.h>

void init_timer (); // Инициализация таймера в течение TIMER_TEST_TIME мс
__int64 exec_rdtsc (); // Текущее значение таймера (exec_rdtsc () / timer_scale == msec)

extern __int64 timer_scale;

#endif // TIMER_HPP

// timer.cpp
#include <timer.h>

const int TIMER_TEST_TIME = 1000; // msec
__int64 timer_scale;

__int64 exec_rdtsc ()
{
    static __int64 result;
    _asm
    {
        rdtsc    // ReaD from Time Stamp Counter
        mov    ebx, offset result
        mov    dword ptr [ebx], eax
        mov    dword ptr [ebx + 4], edx
    }
    return result;
}

void init_timer ()
{
    __int64 start_timer, stop_timer;
    HANDLE current_process = GetCurrentProcess ();
    DWORD common_priority = GetPriorityClass (current_process);
    SetPriorityClass (current_process, REALTIME_PRIORITY_CLASS);
    DWORD tick_count = GetTickCount (), timer = tick_count + TIMER_TEST_TIME;
    start_timer = exec_rdtsc ();
    while (timer > GetTickCount ());
    stop_timer = exec_rdtsc ();
    SetPriorityClass (current_process, common_priority);
    timer_scale = (stop_timer - start_timer) / TIMER_TEST_TIME;
}

Жесткая штука smile

Это сообщение отредактировал(а) zhgutov - 26.4.2005, 12:15
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Sep.
Дата 29.4.2005, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



zhgutov спасибо что выручил, поставил тебе + Добавил в timer.cpp :
Код
void delay(__int64 t)
{
  __int64 n,s;
  s = exec_rdtsc();
  do{
    n=exec_rdtsc();
  }while((t*timer_scale)>(n-s));
}
и получил при delay(1) 2мс минимум. Этого мне оказалось вполне достаточно (движок при 4мс теряет синхронизацию)
А GetTickCount() оказался в winbase.h
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0605 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.