2015-06-03 5 views
2

У меня возникли проблемы с пониманием того, почему тестовый пример, который, как мне кажется, должен проходить, в большинстве случаев терпит неудачу. Я проверил тест до переменной условия и использовал метод wait_for, специально проверив его, чтобы убедиться, что он действительно ждет, по крайней мере, до указанной продолжительности.Условие переменной C++ wait_for не ведет себя как ожидалось

Тестовый фрагмент кода ниже:

TEST_CASE("Condition variable test") 
{ 
    std::mutex m; 
    std::unique_lock<std::mutex> lock(m); 
    std::condition_variable cv; 
    bool ex = false; 
    std::chrono::milliseconds rel_time(50); 

    auto start = std::chrono::steady_clock::now(); 

    cv.wait_for(lock, rel_time, [&ex] {return(ex);}); 

    auto end = std::chrono::steady_clock::now(); 

    REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() >= rel_time.count()); 
} 

я ожидал бы от моего понимания стандарт C++ 11, что это должно пройти все время. По иронии судьбы, если я меняю тип часов на системные часы, я не могу получить тест на провал.

Выдержка из cplusplus.com для condition_variable :: wait_for метод утверждает, что «Если pred задано (2), функция блокирует только, если pred возвращает false, и уведомления могут только разблокировать поток, когда он становится истинным (что особенно полезно для проверки на ложные вызовы пробуждения). Он ведет себя так, как если бы реализован как: return wait_until (lck, chrono :: stable_clock :: now() + rel_time, std :: move (pred));

Это подразумевает, что использование постоянных часов для получения контрольных марок времени - это правильные часы.

Я компилирую среду MinGW с помощью компилятора gcc 4.8.2.

+0

Collin, начало и конец - это точки времени. Я вычитаю временные точки для формирования продолжительности. Я сравниваю измеренную длительность с желаемой продолжительностью. Для этого измерения достаточно разрешения в моей системе. Я увеличил желаемую продолжительность до 500 мс и 5 с, и тест все еще не срабатывает. Мне все же было бы интересно узнать более подробную информацию о том, почему вы считаете, что это плохой тест. –

ответ

3

Это звучит как ошибка в реализации вашего поставщика. Я не вижу, как этот тест может потерпеть неудачу.

FWIW, ваше REQUIRE заявление может быть значительно упрощена:

REQUIRE(end - start >= rel_time); 

сравниваться durations являются всегда точно.

Существует один способ, которым ваш тест, как написано, может быть неудачным: если std::chrono::steady_clock::duration больше миллисекунд, выражение duration_cast<milliseconds>(end - start) может привести к 0 мс. Для защиты от такой плохой реализации вы можете добавить:

static_assert(std::chrono::steady_clock::duration{1} <= std::chrono::milliseconds{1}, 
    "This steady_clock implementation has an outrageously coarse duration"); 
+0

Это может легко выйти из строя, если 'stable_clock' имеет, например, разрешение 16 мс. «Wait_for» может задерживаться на 64 мс, даже если вы запросили 50 мс. –

+0

@CollinDauphinee И что бы не сработало испытание? –

+0

@CollinDauphinee: Если задержки 'wait_for' за 64 мс, то тест в виде записанных проходов, считая' REQUIRE', является хорошим именем. –

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

  • Нет связанных вопросов^_^