Вызов функции WinAPI Sleep() выполняется дольше, чем ожидалось

ОС: Windows 7

При вызове функции WinAPI Sleep() как Sleep (1) поток фактически спит на 15 мс. Я делал это 100 раз в цикле, и общее время сна составляло 1500 мс вместо 100.

Является ли это обычным явлением или я должен быть убежден в том, что что-то не так с моей установкой MOBO, CPU, Windows?

РЕДАКТИРОВАТЬ: Если возможно, вы можете запустить этот код и указать, как долго было время сна. Я позволил своему другу поработать, и на самом деле у него было все на 1 мс.

#include <iostream>
#include <ctime>
#include <windows.h>
void test(void)
{
 std::cout << "Testing 1ms sleep." << std::endl;
 for (unsigned int i = 0; i < 10; i++)
 {
 std::clock_t startClocks = std::clock();
 Sleep(1);
 std::clock_t clocksTaken = std::clock() - startClocks;
 std::cout << "Time: " << clocksTaken << "ms." << std::endl;
 }
}
int main(void)
{
 test();
 std::cin.sync();
 std::cin.get();
 return 0;
}
</windows.h></ctime></iostream>

EDIT2: Кажется, причина, по которой некоторые люди получают 1 мс, - это запуск какой-либо другой программы, которая устанавливает общее разрешение таймера на 1 мс. По умолчанию это должно быть 15.6ms в Windows 7.

7 ответов

Это обычное поведение

Это.

Планировщик оконных потоков работает на квант времени (точная длина зависит от различных факторов, включая версию и версию Windows). Эффективно любая ненулевая задержка округляется до полного кванта.


Сон может привести к тому, что поток будет спать дольше указанного тайм-аута, он гарантирует, что поток будет спать по крайней мере в течение этого периода времени.

Из документации:

  

После того, как интервал ожидания прошел, поток готов к запуску. Если вы укажете 0 миллисекунд, поток отменит оставшуюся часть своего временного фрагмента, но останется готовым. Обратите внимание, что готовый поток не может быть запущен немедленно. Следовательно, поток может не работать до некоторого времени после истечения интервала ожидания. Подробнее см. Приоритеты планирования.

  


Лучшие статьи, которые я нашел относительно времени в Windows, здесь и здесь. Полезная часть заключается в том, что после изменения разрешения мультимедийного таймера (например, timeBeginPeriod (1) за 1 мс), это также влияет на команду Сон, поскольку это влияет на планировщик в целом. Это говорит о том, что достижение 1 мс точности не представляется возможным для ОС без реального времени.


Вы должны проверить разрешение таймера вашего компьютера. Подробнее см. В msdn документации Sleep().


Это довольно нормальное поведение, так как большинство разрешений часов составляют около 10-15 мс. Поэтому, если вы вызываете его со значением, меньшим, чем разрешение часов (в вашем случае 1), ему, вероятно, придется ждать хотя бы одного такта, поэтому он спит дольше, чем вы хотите.

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


Поведение в порядке. Базовое оборудование, версия ОС и даже работающее программное обеспечение влияют привычка ОС по отношению к функции sleep().

Если сон вызывается с dwMilliseconds, меньшим, чем период прерывания системы, вызов будет возвращаться при следующем прерывании. Таким образом, фактическая задержка зависит от времени, в которое был вызван сон (относительно периода прерывания).

Желательно использовать интерфейс мультимедийного таймера, чтобы увеличить частоту прерываний до максимума, поддерживаемого аппаратным обеспечением, когда требуется спящий режим (1).

Подробный обзор функции sleep(), ожидаемых функций таймера, настроек таймера и настроек таймера мультимедиа можно найти в Windows Timestamp Project


(debug или release build?)

Как вы измеряете задержку? вы используете точный метод? (QueryPerformanceCounter)

Я не думаю, что вы должны полагаться на ОС Windows для точного времени; это не операционная система реального времени, и будут внешние "силы", которые украдут время вашего процесса.

licensed under cc by-sa 3.0 with attribution.