Максимальная продолжительность сна: std::this_thread::sleep_for()
не имеет здесь никаких проблем.Вы можете спать сколько угодно.
Точность: std::this_thread::sleep_for()
имеет те же проблемы, что и все другие функции сна, о которых вы упомянули: Вероятно, нет!См. Обновление ниже!
Любая функция сна будет страдать от quirk
того, что она полностью зависит от планировщика в вашей операционной системе, когда ваша задача фактически возобновится.Ваше время сна обычно будет несколько совпадать с минимальным временным интервалом вашего вытесняющего планировщика многозадачности.
Что еще хуже, этот временной интервал не всегда постоянен во всех ОС.
В Linux вы обычноиметь интервалы времени 10 мс и время ожидания менее 10 мс может привести к сну 0 мс.Сон в течение 10 мс может привести к сну на около 10 мс или дольше, потенциально, но не обязательно в соответствии с размером временного интервала.
Короче говоря: вы не можете вообще полагаться ни на одно изфункции сна, в том числе std::this_thread::sleep_for()
.
Существует еще один класс функций сна, которые заняты ожиданием.Это обычно используется при ожидании времени, которое значительно короче, чем временной интервал планирования (скажем, 2 us).Но, конечно, даже это может быть очень неточным, поскольку ваша задача может быть прервана даже в почти бездействующей системе, а затем вы можете добавить 10 мс к времени ожидания 2 us.
В многозадачной операционной системе у вас нетшанс: вы не можете спать точно.Функции сна имеют ошибки, и они даже имеют систематические ошибки, поэтому на практике 100 раз по 10 мс могут спать в интервале от 0 до 2 секунд на практике.
Если у вас есть долгосрочные требования времени, единственный шанс, который у вас есть, этопостоянно запрашивать время настенных часов.
Обновление: эталонные тесты в Linux и macOS:
По крайней мере в Linux и macOS std::this_thread::sleep_for()
довольно точны с точностью до миллисекундыи поэтому не страдают от всех артефактов, которые я описал выше:
Тест Linux: каждый сон вызывается многократно в течение общей продолжительности в одну секунду, и дается реальное среднее время сна (например, усреднениеболее 200 вызовов в спящий режим (5 мс)):
std::this_thread::sleep( 1 ms) slept really 1.13915 ms
std::this_thread::sleep( 2 ms) slept really 2.15215 ms
std::this_thread::sleep( 3 ms) slept really 3.14976 ms
std::this_thread::sleep( 4 ms) slept really 4.15059 ms
std::this_thread::sleep( 5 ms) slept really 5.15062 ms
std::this_thread::sleep( 6 ms) slept really 6.15008 ms
std::this_thread::sleep( 7 ms) slept really 7.14988 ms
std::this_thread::sleep( 8 ms) slept really 8.14979 ms
std::this_thread::sleep( 9 ms) slept really 9.15044 ms
std::this_thread::sleep(10 ms) slept really 10.1504 ms
std::this_thread::sleep(11 ms) slept really 11.1511 ms
std::this_thread::sleep(12 ms) slept really 12.1505 ms
std::this_thread::sleep(13 ms) slept really 13.1504 ms
std::this_thread::sleep(14 ms) slept really 14.1501 ms
std::this_thread::sleep(15 ms) slept really 15.1503 ms
std::this_thread::sleep(16 ms) slept really 16.1499 ms
std::this_thread::sleep(17 ms) slept really 17.1505 ms
std::this_thread::sleep(18 ms) slept really 18.1505 ms
std::this_thread::sleep(19 ms) slept really 19.1504 ms
std::this_thread::sleep(20 ms) slept really 20.1505 ms
То же самое для macOS:
std::this_thread::sleep( 1 ms) slept really 1.27451 ms
std::this_thread::sleep( 2 ms) slept really 2.45646 ms
std::this_thread::sleep( 3 ms) slept really 3.61991 ms
std::this_thread::sleep( 4 ms) slept really 4.77443 ms
std::this_thread::sleep( 5 ms) slept really 5.7994 ms
std::this_thread::sleep( 6 ms) slept really 7.03769 ms
std::this_thread::sleep( 7 ms) slept really 8.13089 ms
std::this_thread::sleep( 8 ms) slept really 9.13276 ms
std::this_thread::sleep( 9 ms) slept really 10.441 ms
std::this_thread::sleep(10 ms) slept really 11.5895 ms
std::this_thread::sleep(11 ms) slept really 12.77 ms
std::this_thread::sleep(12 ms) slept really 13.8207 ms
std::this_thread::sleep(13 ms) slept really 14.9366 ms
std::this_thread::sleep(14 ms) slept really 16.4569 ms
std::this_thread::sleep(15 ms) slept really 17.27 ms
std::this_thread::sleep(16 ms) slept really 18.2013 ms
std::this_thread::sleep(17 ms) slept really 19.6347 ms
std::this_thread::sleep(18 ms) slept really 20.7785 ms
std::this_thread::sleep(19 ms) slept really 22.9571 ms
std::this_thread::sleep(20 ms) slept really 23.2532 ms
Оба запуска выполняются в режиме ожидания.Интересно: в Linux числа становятся более точными в загруженной системе (да, во время сеанса экрана).Планировщик артефактов!Но маленькие!: -)
Это для usleep()
в Linux: тоже довольно точно.Я больше не верю тому, что написал выше:
usleep( 1 ms) slept really 1.148 ms
usleep( 2 ms) slept really 2.152 ms
usleep( 3 ms) slept really 3.151 ms
usleep( 4 ms) slept really 4.151 ms
usleep( 5 ms) slept really 5.149 ms
usleep( 6 ms) slept really 6.149 ms
usleep( 7 ms) slept really 7.149 ms
usleep( 8 ms) slept really 8.150 ms
usleep( 9 ms) slept really 9.150 ms
usleep(10 ms) slept really 10.150 ms
usleep(11 ms) slept really 11.149 ms
usleep(12 ms) slept really 12.149 ms
usleep(13 ms) slept really 13.150 ms
usleep(14 ms) slept really 14.150 ms
usleep(15 ms) slept really 15.149 ms
usleep(16 ms) slept really 16.149 ms
usleep(17 ms) slept really 17.150 ms
usleep(18 ms) slept really 18.150 ms
usleep(19 ms) slept really 19.149 ms
usleep(20 ms) slept really 20.149 ms