Показать сообщение отдельно
  #6  
Старый 28.04.2008, 16:32
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от falabella
Просьба немного изменилась.
Вот код. Его надо адаптировать под делфи, а выделенную части надо переделать на получение не просто тика, а на зависимость от частоты процессора (т,е. t = 1/f, f - количество тиков в секунду, частоту получить через rdtsc). Особенность моего задания именно в том, что мне нужно получать временные задержки основываясь именно на частоте процессора. Чем больше частота, тем выше точность задржки. Вот в чем суть! Надесь, что сейчас вопрос более понятен.
Код:
#include <windows.h> 
#include <iostream> 
#include <conio.h> 

using namespace std; 

class ExactTimer 
{ 
public: 
    typedef void (*CallbackProc)(void); 

    ExactTimer() 
    { 
      Callback = NULL; 
      StartThreadHandle = NULL; 
      RepeatOnce = false; 
      Milliseconds = 1000; 
    } 
    
    ~ExactTimer() 
    { 
      Stop(); 
    } 

    void Start() 
    { 
      Stop(); 
      StartThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(StartThread),(void*)this,NULL,0); 
    } 

    void Stop() 
    { 
      if (StartThreadHandle != NULL) 
      { 
        TerminateThread(StartThreadHandle, 0); 
        CloseHandle(StartThreadHandle); 
        StartThreadHandle = NULL; 
      } 
    } 
    
    void SetMilliseconds(long milliseconds) 
    { 
      Milliseconds = milliseconds; 
    } 

    long GetMilliseconds() const 
    { 
      return Milliseconds; 
    } 

    void SetCallbackProcedure(CallbackProc callback) 
    { 
      Callback = callback; 
    } 

    void SetRepeatOnce(bool repeatOnce) 
    { 
      RepeatOnce = repeatOnce; 
    } 
protected: 
    CallbackProc Callback; 
    bool RepeatOnce; 
    bool Repeat; 
    long Milliseconds; 
    HANDLE StartThreadHandle; 

    static DWORD WINAPI StartThread(void *pExactTimer) 
    { 
      ExactTimer exactTimer = *((ExactTimer*)pExactTimer); 
      LARGE_INTEGER liFrequency, liStartTime, liCurrent; 
      QueryPerformanceFrequency(&liFrequency); 
      __int64 llWaitTime = ((liFrequency.QuadPart / 1000) * exactTimer.Milliseconds); 
      while (true) 
      
{ 
        QueryPerformanceCounter(&liStartTime); 
        QueryPerformanceCounter(&liCurrent); 
        while ((liCurrent.QuadPart - liStartTime.QuadPart) < llWaitTime) 
          QueryPerformanceCounter(&liCurrent); 
        if (exactTimer.Callback != NULL) 
          exactTimer.Callback(); 
        if (exactTimer.RepeatOnce) 
          exactTimer.Stop(); 
      } 
      return 0; 
    }  
}; 

void PrintTheEnd() 
{ 
  cout << " THE END " << endl; 
} 

int main() 
{ 
  ExactTimer t; 
  t.SetRepeatOnce(false); 
  t.SetMilliseconds(100); 
  t.SetCallbackProcedure(PrintTheEnd); 
  t.Start(); 
  _getch(); 
  t.Stop(); 
  _getch(); 
  return 0; 
}

Ну, собственно, весь интересный код лежит в функции ExactTimer exactTimer, остальное - шелуха вокруг. Собственно, как я понимаю, эта функция запускается как отдельный поток. Фактически,она и выполняет расчет времени ожидания в зависимости от частоты проца.

Т.е. тело потока будет выглядеть как-то так:
Код:
var
  AWaitTime : Int64;
  ACurTime, AStartTime : Int64;
  CPUFrq : Int64;
begin
  QueryPerformanceFrequency(CPUFreq);
  AWaitTime := CPUFreq / 1000 * Miliseconds;
  QueryPerformanceCounter(AStartTime);
  QueryPerformanceCounter(ACurTime);
  While Not Terminated Do
    Begin
      If (ACurTime - AStartTime) > AWaitTime Then
        Begin
          AStartTime := ACurTime;
          If Assigned(FCallBack) Then FCallBack;
        End;
      QueryPerformanceCounter(ACurTime);
    End;
end;
Ответить с цитированием