При использовании STD :: Chrono :: наносекунд вместо этого, он является громоздким указать, скажем, 10 минут.
На самом деле, это не делает его громоздким в наименее:
#include <chrono>
#include <iostream>
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
{
std::cout << timeout.count() << '\n';
}
int
main()
{
my_function(true, std::chrono::minutes(10));
}
Выход:
600000000000
Единственный раз, когда вы будете иметь проблемы с nanoseconds
, если вы хотите передать то, что не будет точно конвертировать в nanoseconds
, например picoseconds
, или duration<long, ratio<1, 3>>
(1/3 секунды единиц).
Update
Я намеревался этот ответ будет дополнительная информация для уже принятого ответа, что я думал, был хороший ответ (по sehe). sehe рекомендовал шаблонное решение, которое я также считаю прекрасным.
Если вы хотите принять любойstd::chrono::duration
, даже тот, который вы, возможно, придется truncate or round, то при переходе с удаленного ответа sehe является путь:
template <typename Rep, typename Period>
void my_function(bool work_really_hard, std::chrono::duration<Rep, Period> timeout)
{
// Do stuff, until timeout is reached.
std::this_thread::sleep_for(timeout);
}
Если по каким-то причинам вы не хотите чтобы иметь дело с шаблонами и/или вы довольны тем, что ваши клиенты должны указывать только единицы, которые в точности конвертируются в std::chrono:nanoseconds
, то использование std::chrono:nanoseconds
, как я показал выше, также вполне приемлемо.
Все std::chrono
«предопределенными» единицы:
hours
minutes
seconds
milliseconds
microseconds
nanoseconds
неявно конвертируются в nanoseconds
, и не будет включать в себя любое усечение или округлить ошибку. Переполнение не произойдет, пока вы держите его в двух ярких белых линиях (неясная ссылка на то, чтобы держать свой автомобиль в своей полосе).Пока продолжительность составляет +/- 292 года, вам не нужно беспокоиться о переполнении этими заранее определенными единицами.
В Std-определенные функции, такие как std::this_thread::sleep_for
являются шаблонными, как sehe предполагает, именно по причине желания быть совместимы с каждым chrono:duration
вообразимых (например, 1/3 с плавающей точкой фемтосекундного). Разработчик API может решить, нужна ли им такая гибкость в своем API.
Если мне теперь удалось смутить вас, а не разъяснять, не беспокойтесь слишком много. Если вы решите использовать nanoseconds
, все будет работать точно, без усечения или ошибки округления, или клиент получит ошибку времени компиляции. Будет нет ошибка времени выполнения.
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
{
std::cout << timeout.count() << '\n';
}
int
main()
{
using namespace std;
using namespace std::chrono;
typedef duration<double, pico> picoseconds;
my_function(true, picoseconds(100000.25));
}
test.cpp:15:9: error: no matching function for call to 'my_function'
my_function(true, picoseconds(100000.25));
^~~~~~~~~~~
test.cpp:4:10: note: candidate function not viable: no known conversion from 'duration<double, ratio<[...], 1000000000000>>' to
'duration<long long, ratio<[...], 1000000000>>' for 2nd argument
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
^
1 error generated.
И если клиент получает ошибку во время компиляции, он всегда может использовать duration_cast
работать вокруг него:
my_function(true, duration_cast<nanoseconds>(picoseconds(100000.25))); // Ok
Для получения более подробной информации, пожалуйста, см:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm
Сладкое обновление исходного кода в верхней части этого ответа. В C++ 1у, который мы надеемся, означает C++ 14:
using namespace std::literals;
my_function(true, 10min); // also ok, is equal to 600000000000 nanoseconds
Вопрос: Что бы вы порекомендовали в качестве тайм-аута "бесконечности" (т.е. не тайм-аут)
I сначала попытался бы использовать API, который не занимал бы тайм-аут, и подразумевал, что «не тайм-аут». Например, condition_variable::wait
. Если бы у меня был контроль над API, я бы создал такую подпись без тайм-аута.
В противном случае, я бы создал серию "большой" chrono::durations
:
typedef std::chrono::duration
<
std::int32_t, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>
> days;
typedef std::chrono::duration
<
std::int32_t, std::ratio_multiply<days::period, std::ratio<7>>
> weeks;
typedef std::chrono::duration
<
std::int32_t, std::ratio_multiply<days::period, std::ratio<146097, 400>>
> years;
typedef std::chrono::duration
<
std::int32_t, std::ratio_divide<years::period, std::ratio<12>>
> months;
И тогда я хотел бы использовать один из этих больших длительностей в моем вызове, например:
std::this_thread::sleep_for(years(3));
I не пытались бы максимально увеличить push_things (вы можете нарушить основные допущения, сделанные ОС, например). Просто произвольно выберите что-то смехотворно большое (например, 3 года). Это поймает взгляд вашего кодового обозревателя и, вероятно, заинтересует информативный разговор. :-)
В настоящее время доступны видео: https://www.youtube.com/watch?v=P32hvk8b13M :-)
использовать '' wait_until' или sleep_until' примитивы? IOW, используйте крайний срок, а не тайм-аут – sehe
@sehe Внутренние условия выполнения тайм-аута не относятся к этому вопросу (я не имею никакого контроля над ними). Я просто обеспокоен тем, какой тип использовать для таймаута в сигнатуре функции. – JohnCand
Как насчет миллисекунд? Стандарт _kinda_ указывает время ожидания в миллисекундах. Также - типы 'std :: chrono' выражаются в соотношениях, поэтому вы можете использовать нецелые значения. – Tibor