Может ли кто-нибудь объяснить это интересное поведение с помощью Sleep (1)? - PullRequest
1 голос
/ 14 апреля 2010

Я проверял, как долго различные вызовы Win32 API будут ждать, когда их попросят подождать 1 мс.Я попытался:

:: Sleep (1)
:: WaitForSingleObject (handle, 1)
:: GetQueuedCompletionStatus (handle, & bytes, & key, & overlapped, 1)

Iобнаружил прошедшее время, используя QueryPerformanceCounter и QueryPerformanceFrequency.Прошедшее время составляло около 15 мс большую часть времени, что ожидается и задокументировано по всему Интернету.Однако за короткий промежуток времени ожидание заняло около 2 мс !!!Это происходит последовательно в течение нескольких минут, но теперь оно возвращается к 15 мс.Я не использовал вызовы timeBeginPeriod () и timeEndPeriod!Затем я попробовал то же самое приложение на другой машине, и ожидание постоянно занимает около 2 мс!Обе машины имеют Windows XP SP2, а оборудование должно быть идентичным.Есть ли что-то, что объясняет, почему время ожидания так сильно меняется?ТИА

Ответы [ 5 ]

4 голосов
/ 14 апреля 2010

Thread.Sleep (0) разрешит выполнение любых потоков с одинаковым приоритетом. Thread.Sleep (1) разрешит выполнение любых потоков с одинаковым или более низким приоритетом.

Каждому потоку дается интервал времени для выполнения, прежде чем планировщик позволяет другому потоку выполняться. Как заявляет Billy ONeal, вызов Thread.Sleep оставит остальную часть этого интервала другим потокам (с учетом вышеизложенных соображений приоритета).

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

Существует статья, которая может представлять интерес для темы Thread.Sleep (x) по адресу:

Приоритетное голодание: почему Sleep (1) лучше, чем Sleep (0) и диспетчер баланса Windows

3 голосов
/ 14 апреля 2010

Изменение разрешения таймера может быть выполнено любым процессом в системе, и эффект виден глобально. См. Эту статью о том, как компилятор Hotspot Java обрабатывает время в Windows, в частности:

Обратите внимание, что любое приложение может изменить прерывание таймера и влияет на всю систему. Windows только позволяет сократить период, таким образом гарантируя, что самый короткий запрашиваемый период всеми приложениями является тем, который используется. Если процесс не сбрасывает период, тогда Windows заботится об этом, когда процесс завершается. Причина, по которой виртуальная машина не просто произвольно изменяет частоту прерываний при запуске - она ​​может это сделать, - в том, что возможное влияние на производительность всего оборудования в системе из-за увеличения числа прерываний в 10 раз. Однако другие приложения меняют его, как правило, мультимедийные зрители / проигрыватели.

1 голос
/ 14 апреля 2010

Для суммирования того, что было сказано ранее:

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

Типичные интервалы времени составляют 8,15 мс, в зависимости от архитектуры.

Поток может «отказаться» от временного интервала - обычно Sleep (0) или Sleep (1). Sleep (0) позволяет другому потоку с таким же или более высоким приоритетом работать для следующего отрезка времени. Sleep (1) допускает «любой» поток.

Временной интервал является глобальным и может быть затронут всеми процессами
Даже если вы не измените временной интервал, это может сделать кто-то другой.

Даже если временной интервал не изменяется, вы можете «перепрыгнуть» между двумя разными временами.

Для простоты предположим, что одно ядро, ваш поток и другой поток X.

Если поток X работает с тем же приоритетом, что и у вас, сокращая числа, ваш сон (1) займет весь промежуток времени, 15 мс, что типично для клиентских систем.

Если поток X работает с более низким приоритетом и через 4 мс отказывается от своего собственного временного интервала, ваш сон (1) займет 4 мс.

1 голос
/ 14 апреля 2010

Самая большая вещь, которую sleep(1) делает, - это оставшаяся часть кванта вашего потока. Это полностью зависит от того, сколько квантов вашего потока остается, когда вы звоните sleep.

0 голосов
/ 14 апреля 2010

Я бы сказал, что это зависит только от того, насколько загружен процессор, если нет других процессов / потоков, он мог бы вернуться к вызывающему потоку намного быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...