Я пишу таймер для некоторых сложных коммуникационных приложений в Windows 10 с qt5 и c ++. Я хочу использовать максимум 3 процента процессора с микросекундным разрешением.
Изначально я использовал qTimer (qt5) в этом приложении. Это было хорошо с низким использованием процессора и дружественным интерфейсом для разработчиков. Но это было не совсем так, как мне нужно. Это всего лишь миллисекунда в качестве параметра, но мне нужна микросекунда. И точность таймера не была равна этому разрешению во многих реальных ситуациях, таких как большая нагрузка на процессор. Иногда таймер срабатывает со скоростью 1 миллисекунда, иногда 15 миллисекунд. Вы можете увидеть эту проблему на картинке:
Я искал решение в течение нескольких дней. Но в конце концов я обнаружил, что Windows не является операционной системой реального времени (RTOS) и не дает высокого разрешения и точного таймера.
Я написал собственный точный таймер высокого разрешения с опросом процессора для этой цели. Я разработал синглтон-класс, работающий в отдельной ветке. Он работает с разрешением 10 микросекунд.
Но он потребляет одно логическое ядро в процессоре. Эквивалент 6,25% при ризене 2700.
Для моего приложения это использование ЦП недопустимо. Как я могу уменьшить использование этого процессора, не отдавая высокое разрешение?
Это код, который выполняет работу:
void CsPreciseTimerThread::run()
{
while (true)
{
QMutexLocker locker(&mMutex);
for (int i=0;i<mTimerList.size();i++)
{
CsPreciseTimerMiddleLayer* timer = mTimerList[i];
int interval = timer->getInterval();
if ( (timer->isActive() == true&&timer->remainingTime()<0))
{
timer->emitTimeout();
timer->resetTime();
}
}
}
}
Я попытался уменьшить приоритет потока таймера. Я использовал эти строки:
QThread::start(QThread::Priority::LowestPriority);
И это:
QThread::start(QThread::Priority::IdlePriority);
Эти изменения делают таймер менее точным, но загрузка процессора не уменьшается.
После этого я попытался заставить текущий поток спать в течение нескольких микросекунд в цикле.
QThread::usleep(15);
Как вы могли догадаться, функция сна действительно испортила точность. Иногда таймер спит дольше, чем ожидалось, например, 10 мс или 15 мс.