Как стать автором
Обновить

Комментарии 24

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

Да как бы вообще thread – штука тяжелая, все вроде как давно уже пришли к концепции thread pool. А тут вот так раз – и пусть себе целый thread простаивает.


По мне, так в 99% случаев sleep вообще использовать не стоит. Даже в тестах.

Тоже хотел про это сказать)
Про пароварку так вообще — нужно же рассчитывать, что свет может моргнуть (значит надо помнить сколько ещё готовить осталось), секунда может быть не секундой, а 1,1с, пользователь может захотеть изменить блюдо, но не сможет, те sleep заблокировал поток(отдал ос) итд итп.

А главное, на тех же МК эти задачи отлично решаются с помощью машины состояний и глобального таймера (неважно, реального времени или нет). Если очень хочется, то с помощью ОСРВ.
И чем же вам моргание света мешает использовать sleep?

Моргнул свет — система перезагрузилась, все настройки сбиты, текущее время в пароварке/мультиварке неизвестно (обычно в них нет батарейки для часов). Значит, неизвестно сколько блюдо готовилось до перезагрузки, и сколько ещё надо продолжать его готовить после перезагрузки, и в каком режиме. Регулярные просыпания, например каждые 10 секунд и сохранение в память текущего прогресса решают эту проблему. Sleep на 20 минут наоборот — не даёт реализовать такой функционал.

А что мешает спать по 10 секунд и между ними сохранять состояние?
...
while(time_operation > 0){
	save_state();
	sleep(10*1000);
	time_operation -= 10*1000;
}
...
Я про это и написал — просыпаться каждые 10 секунд. А в статье предлагается сделать sleep на 20 минут:
Проработать в нём 20 минут

Вы непонятно почему спорите, читая невнимательно статью.
Это большой вопрос кто невнимательно читал — в статье НИГДЕ не сказано, что спать нужно именно «одним куском» на 20 минут сразу. Это додумали лично вы.

А в статье лишь было сказано сказано что в подобных ситуациях вообще использование функции sleep — оправдано. Т.к. ожидание привязано не к чему-то происходящему в самой программе, а к внешнему физическому процессу.

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

Получается, хороший пример придумать вообще трудно :)
Плохой пример 1: а автор подумал о гонке между установкой хука на создание окна, и созданием этого самого окна? Кроме того, по коду видно, что засыпает только процесс, задача которого — отдать основному сообщение об открытом файле, и не создающий никакого интерфейса, который мог бы тормозить.
Так нужно сначала ставить хук, поток делать FindWindow и, если окно нашлось — снимать хук, а если нет — ждать событие. Мне это казалось настолько очевидным, что я даже не расписывал.

«засыпает только процесс, задача которого — отдать основному сообщение об открытом файле» — и того юзер ждёт открытия своего файла на 100 мс дольше, чем мог бы ждать.

У меня очень давно сформулировано:


Правило №1
Использование таймера для управления чего нибудь, всегда ошибочно.

Таймер, это всегда эмулятор события. И этот эмулятор, рано или поздно ошибается. Правда, иногда, просто невозможно найти реальный источник сигналов о событиях ("Корректный пример" №2) и тогда приходится использовать таймеры. Но всегда надо ясно осознавать, что это компромисс и все равно ошибка, а программа написанная таким образом, работает неправильно.

Вот да, зашёл почитать про sleep(0) и просто с очень малыми значениями. Особенно если нет SleepEx() или аналога
НЛО прилетело и опубликовало эту надпись здесь

Sleep(0) это не таймер вообще, а управление планировщика. Если я правильно понимаю о чем вы.


Но говоря вообще, меньше интервал таймера – более правильная программа. В пределе, интервал 0 дает правильный алгоритм.

Exponential backoff — хорошее или плохое использование таймера?

Хороший вопрос. Там, где она используется, это происходит от безнадёги — возможности получить сообщение о том, когда можно передавать данные, просто нет. Поэтому алгоритм подбора выдержки использует время в качестве инструмента нахождения консенсуса просто потому, что других инструментов нет.
Функция идёт к планировщику потоков ОС и говорит ему «мы с моим потоком хотели бы отказаться от выделенного нам ресурса процессорного времени, сейчас и ещё на вот столько-то миллисекунд в будущем. Отдайте бедным!». Слегка удивлённый подобной щедростью планировщик выносит функции благодарность от имени процессора, отдаёт оставшийся кусок времени следующему желающему (а такие всегда найдутся) и не включает вызвавший Sleep поток в претенденты на передачу ему контекста выполнения на указанное количество миллисекунд. Красота!

Нет красоты там нет… Вы забыли, что время там выделяется дискретными кусками в зависимости от задания timeBeginPeriod (что в свою очередь зависит от самой ОС и запущенного софта, который в этот timeBeginPeriod полез и поставил то что ему нравится). Отсюда Sleep(1) может длится как примерно 1.1мс так и примерно 15.6мс.
Везде, где тестил последние лет 10, Sleep(1) работал около 1 мс. Паузу в 16 мс при Sleep(1) я реально последний раз видел году в 2005-ом на Windows XP.
Вообще то во времена Win8 Микрософт возвращала 16мс в каких то из апдейтов на ноутбуках, по той причине, что при кванте 16мс значительно меньше потребление энергии от батарейки — больше времени работы в режиме ожидания. В то же время куча программ откручивают назад на 1 (зачастую не имея для этого оснований).

Поэтому поведение этой функции далеко не всегда соответствует ожидаемому.
Спасибо! Понравилось — очень образно!:
Слегка удивлённый подобной щедростью планировщик выносит функции благодарность от имени процессора

В общем ИМХО тема очень сложная — была бы простая, все бы приложения сейчас не тормозили даже на средних ПК :)

Ждать выполнения работы в другом потоке «сколько-то миллисекунд» попросту глупо, поскольку если у нас не ОС реального времени — никто вам не даст никакой гарантии за сколько времени тот второй поток запустится или дойдёт до какого-то этапа своей работы.
Long time ago работал на уже тогда старой RT11 — и в ней было не просто со «Sleep» :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий