Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.09.2010, 12:22   #1
Dasverd2010
 
Регистрация: 01.09.2010
Сообщений: 5
По умолчанию Как заменить sleep в потоке? чтобы получить задержку 5 мили

Здравствуйте Уважаемые!
Мне нужна Ваша помощь.

Есть поток, мне нужно задержать процедуру (Updatedann) на 5 милисек.


Код:
procedure TDRThread.Execute;

begin
 index:=1;

 //Запускаю бесконечный цикл
 while index>0 do
    begin
    Synchronize(Updatedann);
    sleep(5);
   
    if terminated then exit; //Если поток остановлен, то выйти,
    end;
end;


А на самом деле процедура (Updatedann) выполняется только через 15 мсек.

Если вообще убрать sleep, то процедура (Updatedann) выполняется за 0.16 милисек ~(примерно, очень быстро).



Как сделать что бы процедура (Updatedann) в потоке выполнялась через каждые 5 милисек? что бы можно было регулировать задержку.
Dasverd2010 вне форума Ответить с цитированием
Старый 01.09.2010, 13:01   #2
Lemon2009
Пользователь
 
Аватар для Lemon2009
 
Регистрация: 29.07.2009
Сообщений: 72
По умолчанию

может стоит использовать цикл?

while (пока не истекло время) do Sleep(1);

или

while (пока не полностью выполнилась синхронизация) do Sleep(1);
Совершенство в простоте
Lemon2009 вне форума Ответить с цитированием
Старый 01.09.2010, 13:59   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Можете пояснить зачем?

Дело в том, что ответ на этот вопрос, сильно зависит от того, зачем вам это надо.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 01.09.2010, 14:01   #4
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Sleep(1) также бессмысленнен, как и sleep(5). Меньше 15 ни таймер, ни sleep не едят.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 01.09.2010, 14:35   #5
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

В Windows, и тем более в потоке это вообще бессмысленно. Это не система реального времени.
Баламут вне форума Ответить с цитированием
Старый 01.09.2010, 14:48   #6
Dasverd2010
 
Регистрация: 01.09.2010
Сообщений: 5
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Можете пояснить зачем?

Дело в том, что ответ на этот вопрос, сильно зависит от того, зачем вам это надо.

В процедуре (Updatedann) производятся вычисления, после они выводятся на экран в последствии данные будут передаваться оборудованию через RS232.


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

Помогите, в каком направление капать, или привидите пример... Наверника сталкивались.

Последний раз редактировалось Dasverd2010; 01.09.2010 в 14:51.
Dasverd2010 вне форума Ответить с цитированием
Старый 01.09.2010, 15:00   #7
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Про работу с оборудованием я пас.

Но что точно я вам скажу - Synchronize тут совершенно не в тему, потому что он может задержать выполнение на произвольное количество времени. Вам как минимум нужен отдельный поток, который не будет иметь таких блокировок.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 01.09.2010, 15:36   #8
Dasverd2010
 
Регистрация: 01.09.2010
Сообщений: 5
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Про работу с оборудованием я пас.

Но что точно я вам скажу - Synchronize тут совершенно не в тему, потому что он может задержать выполнение на произвольное количество времени. Вам как минимум нужен отдельный поток, который не будет иметь таких блокировок.
Оборудование допустим, я не буду использовать. Help me...
Dasverd2010 вне форума Ответить с цитированием
Старый 01.09.2010, 15:42   #9
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Вы же только что сказали:

Цитата:
данные будут передаваться оборудованию через RS232
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 07.09.2010, 11:36   #10
Dasverd2010
 
Регистрация: 01.09.2010
Сообщений: 5
Радость

Цитата:
Сообщение от Alex Cones Посмотреть сообщение
Sleep(1) также бессмысленнен, как и sleep(5). Меньше 15 ни таймер, ни sleep не едят.
Проблему я свою решил, думаю нужно поделится.

Я замерял время задержки (sleep), функцией:

Код:
      var
     NewTim, OldTim, VipTim      :TDateTime;
     Hour, Min, Sec, MSec         :Word;

     Begin
      NewTim:=Now;

       // задержка 15 милисекунд
      sleep(15);  
      //(или фукция которую Вы хотите измерить)

      OldTim:=Now;
      VipTim:=OldTim-NewTim;
      DecodeTime(VipTim, Hour, Min, Sec, MSec); 
      
      //перевожу в милисекунды 
      VipTim:=Hour;
      VipTim:=VipTim*3600;
      VipTim:=VipTim+Min*60;
      VipTim:=VipTim+Sec;
      VipTim:=VipTim*1000+MSec;
      
      ShowMessage('Время выполнения фукции = '+floattostr(VipTim)+' милисек');
     End;
Оказывается таким способом можно считать врямя выполнения функции, но если функция выполняется быстрее 15 милисекунд, то бесмыссленно.

Вот результаты:

при sleep(15);
Будет выводится сообщение: (Время выполнения фукции = ~ 15 милисек)

при sleep(5);
Будет выводится сообщение: (Время выполнения фукции = ~15 милисек)


Более точные замеры можно производить следующем способом:

С помощью функций (QueryPerformanceFrequency, QueryPerformanceCounter)

QueryPerformanceCounter - функция Win32 API.
QueryPerformanceFrequency - возвращает частоту счётчика count/sec.
QueryPerformanceCounter - возвращает текущее значение счетчика с высоким разрешением производительности.

Код:
  var
 Ctr1, Ctr2, Freq,Overhead: int64; 
 R: extended; 

  Begin
   QueryPerformanceFrequency(Freq); 
   QueryPerformanceCounter(Ctr1); 
   QueryPerformanceCounter(Ctr2); 
   Overhead := Ctr2 - Ctr1; 
   QueryPerformanceCounter(Ctr1); 

   //здесь Ваша функция или процедура которую Вы хотите измерить
   // допустим задержка sleep(5);

   sleep(5);

   QueryPerformanceCounter(Ctr2); 
   R := ((Ctr2 - Ctr1) - Overhead) / Freq; 
   showmessage( 'Ваша функция выполнилась за ' + FloatToStr(R) + '  секунд');
Результат: Ваша функция выполнилась за 0,0049975 секунд



Следовательно, функция sleep(1) производит задержку в 1 милисекунду, только измерять нужно функциями (QueryPerformanceFrequency, QueryPerformanceCounter).

Так же я нашел способ задержки функции в микросекундах:

Код:
procedure DelayUS(MicroS:int64); // Ожидание N microSec
var
  Frq_Base, Time_memo, Time_now, dif: Int64;
begin
  if QueryPerformanceFrequency(Frq_Base) then // Частота ПК
    begin
      QueryPerformanceCounter(Time_memo);        // начальное значение
      repeat
      QueryPerformanceCounter(Time_now);
      dif := ((Time_now - Time_memo) * 1000000) div Frq_Base;
      until dif > MicroS;
    end;
end;



Begin

DelayUS(4550); // Задержка микросек

End;

Если возник интерес или вопросы стучите в аську 221-955-95 (четыре). Ник: RAKETA буду рад обсудить

Продолжаем обсуждать...

Последний раз редактировалось Dasverd2010; 07.09.2010 в 11:51.
Dasverd2010 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как округлить милисекунды в кол-во сек и мили сек? XerSon Общие вопросы Delphi 2 09.06.2010 10:26
Как приостаносить поток до события в другом потоке Sionus Помощь студентам 2 30.03.2010 21:51
как сделать паузу (или задержку) в цыкле : с# Natok Помощь студентам 7 30.05.2009 12:55
Число N, заменить одну из его цифр, чтобы получилось число, max близкое к некоторой степени двойки urgu_st Помощь студентам 13 23.10.2007 09:14
Как организовать задержку выполнения?? Kenifer Общие вопросы Delphi 12 03.09.2007 21:56