Что происходит, когда GetTickCount () переносится?

Считайте подчеркивание символом подстановки. Используйте [_].

select * from mn_table where status='Y' and upper(pl_name) like '%[_]5M[_]%';
14
задан Scott Langham 7 April 2009 в 23:10
поделиться

8 ответов

Из документов:

Прошедшее время хранится как значение DWORD. Поэтому время повторится, чтобы обнулить, если система будет выполняться непрерывно в течение 49,7 дней. Для предотвращения этой проблемы используйте GetTickCount64. Иначе проверьте на водосливное условие при сравнении времен.

Однако DWORD не подписан - таким образом, необходимо быть хорошо. 0 - "очень большое количество" = "небольшое число" (принимающий Вас не имеют никакой проверки переполнения активной, конечно). У меня было предыдущее редактирование, которое предположило, что Вы получите отрицательное число, но это было, прежде чем я принял во внимание, что DWORD не подписан.

У Вас все еще будет проблема, если операция займет чуть менее чем 49,7 дней все же. Это не может быть проблемой для Вас ;)

Один способ протестировать состоял бы в том, чтобы погасить GetTickCount() метод, таким образом, Вы могли записать модульные тесты, где Вы явно заставляете его перенестись. С другой стороны, если Вы действительно только сомневаетесь относительно арифметической части, можно легко записать модульные тесты на это :) Действительно, то, что число прибывает из системных часов, в значительной степени не важно, пока Вы знаете поведение, когда это переносится - и это указано в документации.

13
ответ дан 1 December 2019 в 06:59
поделиться

Если вы хотите проверить, что происходит при переносе GetTickCount () , вы можете включить проверку приложения. Тест TimeRollOver.

Из Использование верификатора приложения в жизненном цикле разработки программного обеспечения :

TimeRollOver заставляет API-интерфейсы GetTickCount и TimeGetTime выполнять пролонгацию быстрее, чем обычно. Это позволяет приложениям легче тестировать обработку смены времени.

7
ответ дан 1 December 2019 в 06:59
поделиться

Я недавно натыкался на ту проблему. Код, который я работал над используемым GetTickCount () в наборе мест, чтобы определить, проводила ли программа слишком много времени на конкретной задаче и раз так она была бы тайм-аут, что задача и переносит ее для более позднего выполнения. То, что произошло бы, - то, что, если бы GetTickCount () перенесся в течение одного из периодов измерения, он вызвал бы код к тайм-ауту преждевременно. Это было сервисом, который работает постоянно, поэтому каждые 49 дней, он имел бы легкое отклонение.

Я зафиксировал его путем записи класса таймера, который использовал GetTickCount () внутренне, но обнаружил когда значение, перенесенное и компенсированное его.

2
ответ дан 1 December 2019 в 06:59
поделиться

Вы можете протестировать его;) - У меня есть простое тестовое приложение, которое запустит приложение и подключит GetTickCount () в нем, чтобы вы могли управлять им из графического интерфейса тестового приложения. Я написал это как отключение вызовов GetTickCount () в некоторых приложениях не так просто.

TickShifter бесплатен и доступен здесь: http://www.lenholgate.com/ blog / 2006/04 / tickshifter-v02.html

Я написал его во время написания серии статей по разработке через тестирование, в которой использовался некоторый код, который использовал GetTickCount () неработающим способом.

Статьи доступны здесь, если вам интересно: http://www.lenholgate.com/blog/2004/05/practical-testing.html

Тем не менее, в итоге ваш код будет работать ...

1
ответ дан 1 December 2019 в 06:59
поделиться

Конечно, необходимо обработать эту галочку, переносят проблему.

Дескрипторы ядра Linux такая галочка переносят проблему со следующим приемом:

#define time_after (a, b) ((длинный) (b) - (длинный) (a) <0))

Идея брошена неподписанная к со знаком, и сравните их значение, затем только если |a-b | <2^30, затем перенос не влияет на результат.

Вы можете иметь попытку с этим приемом и добраться, изучают, почему он работает.

Так как DWORD является также неподписанным интервалом, этот прием должен также работы для окон.

Таким образом, Вы кодируете, мог быть sth как:

константа интервал DWORD = 20000;

DWORD отсчитывает = GetTickCount () + интервал;

в то время как (верный) {

DoTasksThatTakeVariableTime();

if(time_after(ticks, GetTickCount())
{
    DoIntervalTasks();
    ticks = GetTickCount() + interval;
} 

}

Только если интервал меньше, чем 0x2^30, это работает.

1
ответ дан 1 December 2019 в 06:59
поделиться

Я бы посоветовал рассчитать фактический прошедший период между двумя тактами, не полагаясь на компилятор, который сделает это за вас:

const DWORD interval = 20000;

#define TICKS_DIFF(prev, cur) ((cur) >= (prev)) ? ((cur)-(prev)) : ((0xFFFFFFFF-(prev))+1+(cur))

DWORD ticks = GetTickCount();
while(true)
{
    DoTasksThatTakeVariableTime();

    DWORD curticks = GetTickCount();
    if( TICKS_DIFF(ticks, curticks) > interval )
    {
        DoIntervalTasks();
        ticks = GetTickCount();
    }
}
4
ответ дан 1 December 2019 в 06:59
поделиться

Происходит Большой взрыв. Ой, извините, большой взрыв накрывает.

1
ответ дан 1 December 2019 в 06:59
поделиться

Эта статья мне помогла, но я думаю, что в ней есть ошибка:

#define TICKS_DIFF(prev, cur) ((cur) >= (prev)) ? ((cur)-(prev)) : ((0xFFFFFFFF-(prev))+(cur))

Когда я тестировал это в точке перехода, я обнаружил, что она отключена на 1.

Что сработало для меня было:

define TICKS_DIFF(prev, cur) ((cur) >= (prev)) ? ((cur)-(prev)) : ((0xFFFFFFFF-(prev))+(cur)+1)
1
ответ дан 1 December 2019 в 06:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: