2016-10-04 3 views
7

В стандарте C++ 11 говорится о том, что должно произойти, если системные часы настроены так, что точка времени, прошедшая до sleep_until(), теперь в прошлом, но я не вижу нигде, которая обращается к случаю, когда указанный момент времени уже в прошлом.Является ли поведение корректным, когда `sleep_until()` указывает время в прошлом?

Я просто что-то пропустил, или это действительно не указано - даже как UB или реализация?

Аналогичный вопрос возникает, если sleep_for() вызывается с отрицательной продолжительностью.

+0

Это не конкретный случай кодирования или проблема, которую вы здесь адресуете. Это скорее дискуссия – Rockbar

+5

@ Rockbar: Это чрезвычайно конкретный вопрос и совершенно корректный вопрос. –

+0

Как я помню, спецификация предоставляет разные часы. Некоторые из них гарантированно сильно монотонно увеличиваются (не прыгают назад), другие - нет. –

ответ

1

Вы слишком анализируете это.

Является ли стандарт явно «если целевое время в прошлом, не будет блока или ожидания»? №

Означает ли это, чтобы объяснить, как временной шаг сократит или уничтожит тайм-аут? Да. Кроме того, он определяет эти таймауты с точки зрения относительных тайм-аутов.

Цель, я думаю, довольно ясна. Это одна из тех ситуаций, в которых вы может, но должны вывести его из английской формулировки: если тайм-аут немедленно будет удовлетворен, ничего не произойдет.

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

+0

Даже если бы это было в будущем во время вызова, это может быть в прошлом, когда управление приходит к реализации планировщиком. Поэтому я не уверен, что не существует неотъемлемой проблемы для указания поведения для «прошлых» времен. –

+0

@ JohannesSchaub-litb: Это проблема реализации –

+0

С другой стороны, могут возникнуть проблемы с указанием времени прохождения в будущем, однако для монотонных часов возможно прохождение времени, которое гарантировано в прошлом. –

0

From here

Блокирует выполнение текущего потока до указанного sleep_time достигнута.

т. Е. Если время в прошлом, то оно не будет блокироваться очень долго.

+2

cppreference.com не является стандартным документом стандарта ISO –

+0

Я найду более точную ссылку: P – UKMonkey

+0

Отсюда http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337 .pdf «Блокирует вызывающий поток для абсолютного таймаута» Довольно ясно, что если абсолютный тайм-аут в прошлом, то блокировка истекает довольно быстро. – UKMonkey

4

Расчет времени, до которого спать и звонить sleep_until() не является атомарным. Возможно, вы вычисляете время, затем происходит переключение контекста, перегрузка системы, обмен и фактический вызов на sleep_until() происходит намного позже. Поэтому, если sleep_until() не проснется, когда время в прошлом, тогда это бесполезно, потому что в такой ситуации вы никогда не можете быть уверены, что ваш поток будет пробужден.

Требования к функции указаны в разделе 30.2.4 стандарта. И это указывает, что время возврата должно быть Ct + Di + Dm, где Ct - это время, которое вы указали, Di - это задержка, вызванная перебором прерывания, возвратом функции и планированием, а Dm - задержка, вызванная конфликтом ресурсов. В таком случае Di включает время, прошедшее до того, как вы вызвали sleep_until(), и функция вернется, как только это возможно.

+0

Я не согласен - Di описывается как «качество выполнения» задержки. То, о чем мы говорим, является логическим вопросом, который остался бы, даже если Di и Dm («задержка управления качеством») были равны нулю. – Jeremy

+0

'sleep_until' требуется для возврата в Ct + <время, когда мы ожидаем, что другие потоки освободят CPU> + <время, необходимое для планирования нашего потока>. В этом случае нам нужно много времени, чтобы запланировать его, потому что мы хотим, чтобы это было сделано вчера. –

+1

Да, тот факт, что любая задержка может быть внедрена в любом месте вашей программы, означает, что когда вы вызываете 'std :: sleep_until (x)', x уже может быть в прошлом. Даже если вы делаете 'if (x> SomeClock :: now()) std :: sleep_until (x);'. В этой связи единственной разумной/надежной реализацией является рассмотрение тайм-аута в прошлом как (уже) достигнутого. – ysdx

Смежные вопросы