Конференция "Прочее" » WaitableTimer vs Sleep
 
  • DayGaykin © (30.03.16 09:51) [0]
    Не так давно изучал php-шный usleep и возник вопрос, почему они реализовали его через WaitableTimer, а не через обычный Sleep (или цикл слипов, для задержек более 2^32 usec):

    https://github.com/php/php-src/blob/master/win32/time.c
    Какое этому объяснение?
  • DayGaykin © (30.03.16 09:58) [1]
    Поторопился я. Перепутал милли- и микро- секунды, этим все и объясняется.
  • DVM © (30.03.16 14:11) [2]
    Дело не только в милли или микросекундах скорее всего, просто WaitableTimer - более правильный путь под Windows.
  • DayGaykin © (30.03.16 16:37) [3]
    Объяснил
  • DayGaykin © (30.03.16 16:37) [4]
    Объяснил
  • Pavia © (30.03.16 17:22) [5]

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

    Скорее дело в APC.
  • DVM © (30.03.16 22:16) [6]

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

    Ну очевидно же, что при больших интервалах ожидания Sleep вызываемый периодически в цикле вынуждает поток пробуждаться, что препятствует выгрузке кода в файл подкачки, например. WaitForXXX не препятствуют и кроме того могут быть прерваны в любой момент времени.
  • Pavia © (31.03.16 08:47) [7]

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

    А с чего вы взяли? Если верить MSDN то приоритет у WaitForXXX и sleep аналогичны. И по идеи должны работать  одинаково с подкачкой.
    А вот WaitableTimer работает на APC, который завязан на прямую на прерывания. И их число может доходит до 10 000 в секунду.  
    Предположу что WaitableTimer может выдерживать паузы с точность до 10 мкс.
    А на практике надо померить посмотреть.
  • Игорь Шевченко © (31.03.16 10:13) [8]
    Pavia ©   (31.03.16 08:47) [7]

    "Вы, сударь, ерунду говорите. И хуже всего то, что говорите безапеляционно и уверенно"
  • DVM © (31.03.16 10:19) [9]

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


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

    Дело не в приоритете. Еще раз. Чтобы сделать задержку на большой интервал с помощью Sleep и одновременно иметь возможность прервать ожидание ничего не остается другого как поставить Sleep в цикле указав ему малый интервал и там в же в цикле периодически проверять не вышел ли большой интервал. Поток будет постоянно просыпаться после выхода из очередного Sleep. С WaitFor функциями (с помощью которых можно ожидать в том числе и WaitableTimer) поток будет спать до тех пор пока не наступит событие. И прервать его всегда можно. Разница налицо.
  • DayGaykin © (31.03.16 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 © (31.03.16 11:19) [11]

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

    У меня были хорошие учителя, которые никогда не ошибаются. ;-)
  • DVM © (31.03.16 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 © (31.03.16 16:23) [13]

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

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

    Расскажешь подробнее?
  • DayGaykin © (31.03.16 17:44) [15]

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

    Зачем? Троллей кормить?
  • Inovet © (31.03.16 17:47) [16]
    > [15] DayGaykin ©   (31.03.16 17:44)

    А кто здесь тролли? Вроде бы внятно объяснили разницу. Sleep() не предназначена для выдержки интервалов времени вооще-то. Откуда такое желание её прикрутить для этих целей.
  • KSergey © (01.04.16 10:08) [17]
    > Inovet ©   (31.03.16 17:47) [16]
    > Sleep() не предназначена для выдержки интервалов времени вооще-то.

    Предназначен, если нет время ожидания прервать по внешнему событию.
    Если надо точно заснуть на все 50 дней - то слип подходящее решение.
  • DVM © (01.04.16 10:28) [18]

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


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

    И как мы программу прерывать будем со слипом на 50 дней? Или будем крутить слип в цикле с маленьким интервалом?
  • KSergey © (01.04.16 10:56) [19]
    Прочитайте внимательно.
    По условиям задачи нам надо заснуть ан все 50 дней без прерывания сна.
    Что еще вас беспокоит?
  • DVM © (01.04.16 11:17) [20]

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


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

    По условиям какой задачи? Придуманной? В жизни так не бывает, так бывает только в теории.
    Всегда может понадобиться перезагрузка службы, которая 50 дней чего то ждет и что в этом случае ее надо будет прибивать что ли с потерей данных?
    Использующих Sleep для ожидания интервалов времени длиннее секунды - надо гнать как профнепригодных. Да и для малых интервалов есть более надежные, точные решения.
  • KSergey © (01.04.16 12:14) [21]
    > есть более надежные,

    В чем ненадёжность Sleep()?
  • DVM © (01.04.16 12:55) [22]

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

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

    Более подробно о ее недостатках тут:
    https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686298(v=vs.85).aspx
  • KSergey © (01.04.16 13:14) [23]
    Ненадёжность-то в чем?
    Она что, не всегда работает?

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

    В любом случае было познавательно, спасибо.
  • Inovet © (01.04.16 18:43) [24]
    > [23] KSergey ©   (01.04.16 13:14)
    > "заснуть на 50 дней" - Sleep отлично подходит

    Спасибо за общение, но от себя маленько поправлю: отдать другим своё бесполезное время на 50 дней.:)
Есть новые Нет новых   [134434   +28][b:0][p:0.001]