Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2017.03.26;
Скачать: [xml.tar.bz2];

Вниз

WaitableTimer vs Sleep   Найти похожие ветки 

 
DayGaykin ©   (2016-03-30 09:51) [0]

Не так давно изучал php-шный usleep и возник вопрос, почему они реализовали его через WaitableTimer, а не через обычный Sleep (или цикл слипов, для задержек более 2^32 usec):

https://github.com/php/php-src/blob/master/win32/time.c
Какое этому объяснение?


 
DayGaykin ©   (2016-03-30 09:58) [1]

Поторопился я. Перепутал милли- и микро- секунды, этим все и объясняется.


 
DVM ©   (2016-03-30 14:11) [2]

Дело не только в милли или микросекундах скорее всего, просто WaitableTimer - более правильный путь под Windows.


 
DayGaykin ©   (2016-03-30 16:37) [3]

Объяснил


 
DayGaykin ©   (2016-03-30 16:37) [4]

Объяснил


 
Pavia ©   (2016-03-30 17:22) [5]


> Дело не только в милли или микросекундах скорее всего, просто
> WaitableTimer - более правильный путь под Windows.

Скорее дело в APC.


 
DVM ©   (2016-03-30 22:16) [6]


> DayGaykin ©   (30.03.16 16:37) [4]
> Объяснил

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


 
Pavia ©   (2016-03-31 08:47) [7]


> Ну очевидно же, что при больших интервалах ожидания Sleep
> вызываемый периодически в цикле вынуждает поток пробуждаться,
>  что препятствует выгрузке кода в файл подкачки, например.
>  WaitForXXX не препятствуют и кроме того могут быть прерваны
> в любой момент времени.

А с чего вы взяли? Если верить MSDN то приоритет у WaitForXXX и sleep аналогичны. И по идеи должны работать  одинаково с подкачкой.
А вот WaitableTimer работает на APC, который завязан на прямую на прерывания. И их число может доходит до 10 000 в секунду.  
Предположу что WaitableTimer может выдерживать паузы с точность до 10 мкс.
А на практике надо померить посмотреть.


 
Игорь Шевченко ©   (2016-03-31 10:13) [8]

Pavia ©   (31.03.16 08:47) [7]

"Вы, сударь, ерунду говорите. И хуже всего то, что говорите безапеляционно и уверенно"


 
DVM ©   (2016-03-31 10:19) [9]


> Pavia ©   (31.03.16 08:47) [7]


> А с чего вы взяли? Если верить MSDN то приоритет у WaitForXXX
> и sleep аналогичны.

Дело не в приоритете. Еще раз. Чтобы сделать задержку на большой интервал с помощью Sleep и одновременно иметь возможность прервать ожидание ничего не остается другого как поставить Sleep в цикле указав ему малый интервал и там в же в цикле периодически проверять не вышел ли большой интервал. Поток будет постоянно просыпаться после выхода из очередного Sleep. С WaitFor функциями (с помощью которых можно ожидать в том числе и WaitableTimer) поток будет спать до тех пор пока не наступит событие. И прервать его всегда можно. Разница налицо.


 
DayGaykin ©   (2016-03-31 11:08) [10]


> DVM ©   (31.03.16 10:19) [9]

По поводу первого аргумента: "малый интервал" - это примерно 50 дней. Не слишком накладно поднимать из подкачки код раз в 50 дней.

В коде, что я привел в ссылке handle - локальная переменная. Я не уверен, но мне кажется, это означает, что прерывать в любой момент его никто не захочет.
К тому-же параметр функции - int (насколько я понимаю в си - это тоже 32 бита), поэтому слишком большой интервал для sleep задать и не получится.

Поэтому сделаю вывод о том, что причина использования таймера в его большей детализации.


PHPAPI int usleep(unsigned int useconds)
{
HANDLE timer;
LARGE_INTEGER due;

due.QuadPart = -(10 * (__int64)useconds);

timer = CreateWaitableTimer(NULL, TRUE, NULL);
SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
return 0;
}


 
Pavia ©   (2016-03-31 11:19) [11]


> "Вы, сударь, ерунду говорите. И хуже всего то, что говорите
> безапеляционно и уверенно"

У меня были хорошие учителя, которые никогда не ошибаются. ;-)


 
DVM ©   (2016-03-31 13:20) [12]


> DayGaykin ©   (31.03.16 11:08) [10]
>


> По поводу первого аргумента: "малый интервал" - это примерно
> 50 дней. Не слишком накладно поднимать из подкачки код раз
> в 50 дней.

Ты тоже ничего не понял. В версии со Sleep у тебя не написано Sleep(50 дней). Нормальные люди же не пишут Sleep(50 дней)? Или я ошибаюсь?

Там написано Sleep(несколько секунд или того меньше) и этот Sleep засунут в цикл. Соответственно поток этот будет просыпаться много-много раз за эти 50 дней за каким то лешим, хотя мог бы спокойно себе спать 50 дней и быть выгруженным. В варианте с таймером поток спит ровно 50 дней.

Вообще глупость ждать 50 дней, что таймером, что слипом.


> Поэтому сделаю вывод о том, что причина использования таймера
> в его большей детализации.
>

Ну не особенно большая.
Под Windows есть способ выдерживать точность вплоть до наносекунд, но ценой полной загрузки одного ядра.


 
DayGaykin ©   (2016-03-31 16:23) [13]


> Нормальные люди же не пишут Sleep(50 дней)? Или я ошибаюсь?

Нормальные люди применят немного математики.


 
Inovet ©   (2016-03-31 17:36) [14]

> [13] DayGaykin ©   (31.03.16 16:23)
> Нормальные люди применят немного математики

Расскажешь подробнее?


 
DayGaykin ©   (2016-03-31 17:44) [15]


> Расскажешь подробнее?

Зачем? Троллей кормить?


 
Inovet ©   (2016-03-31 17:47) [16]

> [15] DayGaykin ©   (31.03.16 17:44)

А кто здесь тролли? Вроде бы внятно объяснили разницу. Sleep() не предназначена для выдержки интервалов времени вооще-то. Откуда такое желание её прикрутить для этих целей.


 
KSergey ©   (2016-04-01 10:08) [17]

> Inovet ©   (31.03.16 17:47) [16]
> Sleep() не предназначена для выдержки интервалов времени вооще-то.

Предназначен, если нет время ожидания прервать по внешнему событию.
Если надо точно заснуть на все 50 дней - то слип подходящее решение.


 
DVM ©   (2016-04-01 10:28) [18]


> KSergey ©   (01.04.16 10:08) [17]


> Если надо точно заснуть на все 50 дней - то слип подходящее
> решение.

И как мы программу прерывать будем со слипом на 50 дней? Или будем крутить слип в цикле с маленьким интервалом?


 
KSergey ©   (2016-04-01 10:56) [19]

Прочитайте внимательно.
По условиям задачи нам надо заснуть ан все 50 дней без прерывания сна.
Что еще вас беспокоит?


 
DVM ©   (2016-04-01 11:17) [20]


> KSergey ©   (01.04.16 10:56) [19]


> По условиям задачи нам надо заснуть ан все 50 дней без прерывания
> сна.

По условиям какой задачи? Придуманной? В жизни так не бывает, так бывает только в теории.
Всегда может понадобиться перезагрузка службы, которая 50 дней чего то ждет и что в этом случае ее надо будет прибивать что ли с потерей данных?
Использующих Sleep для ожидания интервалов времени длиннее секунды - надо гнать как профнепригодных. Да и для малых интервалов есть более надежные, точные решения.


 
KSergey ©   (2016-04-01 12:14) [21]

> есть более надежные,

В чем ненадёжность Sleep()?


 
DVM ©   (2016-04-01 12:55) [22]


> В чем ненадёжность Sleep()?

В низкой разрешающей способности. В отсутствии вообще каких-либо гарантий выдерживания малых интервалов. Конечно, можно пытаться улучшить разрешающую способность путем вызова timeBeginPeriod(), но этот костыль нельзя применять на постоянной основе, т.к. это может пагубно отразиться на многих вещах, таких как часы и прочее. Но не это главное. Sleep - это не функция для ожидания временных интервалов, ее назначение - другое - заставлять поток отказываться от выделенного ему процессорного времени, что не одно и то же. Для ожидания в Windows есть таймеры и функции ожидания.

Более подробно о ее недостатках тут:
https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686298(v=vs.85).aspx


 
KSergey ©   (2016-04-01 13:14) [23]

Ненадёжность-то в чем?
Она что, не всегда работает?

Я таки останусь при своём мнении,что для "заснуть на 50 дней" - Sleep отлично подходит. Заметьте, не "подождать чего-то", а "заснуть на 50 дней".

В любом случае было познавательно, спасибо.


 
Inovet ©   (2016-04-01 18:43) [24]

> [23] KSergey ©   (01.04.16 13:14)
> "заснуть на 50 дней" - Sleep отлично подходит

Спасибо за общение, но от себя маленько поправлю: отдать другим своё бесполезное время на 50 дней.:)



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2017.03.26;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.001 c
15-1459185260
d2pak
2016-03-28 20:14
2017.03.26
Организация буфера видео потока


15-1458782603
Kilkennycat
2016-03-24 04:23
2017.03.26
Защита прав потребителя


4-1282048057
mc.fly
2010-08-17 16:27
2017.03.26
Как создать буффер-изображение в памяти? Без VCL.


15-1459546202
Юрий
2016-04-02 00:30
2017.03.26
С днем рождения ! 2 апреля 2016 суббота


4-1282284939
Dmitriy
2010-08-20 10:15
2017.03.26
перерисовка надписи





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский