В C ++ я могу периодически вызывать функции в диапазоне миллисекунды используя мультимедийный таймер Windows следующим образом:
timeSetEvent(intPeriod_Milliseconds, 0, vidTimerCallback, ...., TIME_PERIODIC )
где intPeriod_Milliseconds
целочисленная переменная с требуемым периодом в миллисекундах.
Как я могу получить функцию vidTimerCallback
быть вызванным каждые 0,5 миллисекунды или что-то в диапазоне микросекунд?
Теперь у меня есть что-то вроде этого:
#include <windows.h>
double PCFreq = 0.0;
__int64 CounterStart = 0;
void StartCounter()
{
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li))
cout << "QueryPerformanceFrequency failed!\n";
PCFreq = double(li.QuadPart)/1000.0;
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
double GetCounter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart-CounterStart)/PCFreq;
}
int main()
{
StartCounter();
Sleep(1000);
cout << GetCounter() <<"\n"; //It prints accurate time like 998
return 0;
}
Но я не могу улучшить его, чтобы периодически вызывать функцию.
У меня есть что-то похожее на эту ситуацию с использованием класса Вот.
Кроме того, у меня есть кое-что, что работает очень хорошо, но это для C # не C ++ (Вот).
Этот код C # использует горячий цикл ожидания для измерения времени. Класс .NET Stopwatch является оболочкой для QueryPerformanceCounter (), вы также можете использовать это. Метод Thread.SpinWait () является оболочкой для YieldProcessor (), вы также можете использовать это. Аргумент — это просто количество раз, которое вы вызываете, использование 10 довольно произвольно.
Имейте в виду, что это не ожидание, о котором знает планировщик потока. Что касается этого, вы прожигаете свой квантовый поток, никогда не уступая. И, конечно же, это ядро не делает ничего очень полезного. YieldProcessor () просто избегает поджога процессора, выполняя инструкцию PAUSE. Следствием этого является то, что ваш таймер будет работать плохо, когда машина загружается и другие потоки конкурируют за обслуживание ЦП. Ваша нить пойдет в собачью будку на некоторое время после того, как она обгорела, 45 мсек вполне нормально. Удостоверьтесь, что это не вредно, это почти всегда так. Повышение приоритета потоков немного помогает, вы все равно не можете конкурировать с потоками ядра. В частности, видео и аудио драйверы дадут вам мигрень.
У мультимедийного таймера такой проблемы нет, но, конечно, вы не можете опускаться ниже 1 мс. Вы должны использовать CreateTimerQueueTimer () во всех современных версиях Windows, это не страдает от жалкие побочные эффекты вызова timeBeginPeriod (). Настоятельно рекомендуется над горячей петлей ожидания.
Ты не можешь Windows не является операционной системой реального времени, поэтому даже если бы в ней были функции, принимающие микросекундные параметры, или же вы должны были спроектировать свой собственный планировщик поверх Windows, вы все равно не смогли бы выполнять некоторые функции с такой скоростью. На самом деле, Windows, насколько я знаю, не гарантирует каких-либо реальных жестких ограничений на выполнение, когда конкретный поток будет разбужен. Как правило, он работает с разрешением около 15 миллисекунд, поэтому, если вы не вызовете TimeBeginPeriod (1) где-нибудь в своем приложении, запрос Windows на выполнение Sleep (1), скорее всего, будет спать 15 мсек.
Я не уверен, что вы пытаетесь достичь, но из того, что я вижу, похоже, что вы пытаетесь создать какую-то особую команду ожидания?
void CustomWait(double MStoWait)
{
double StartCount = double( GetCounter() + MStoWait );
while(GetCounter() <= StartCount) {}
printf("%f\n" ,GetCounter());
}
И тогда цикл while в главном
while(1)
{
CustomWait(500.0);
//do stuff
}