Чтобы не допустить постоянных ошибок в цикле (которые обычно неизвестны), вы можете спать до времени точка вместо для времени продолжительность . Используя библиотеки C ++ <chrono>
и <thread>
, это невероятно просто:
#include <chrono>
#include <iostream>
#include <thread>
int
main()
{
using namespace std;
using namespace std::chrono;
auto t0 = steady_clock::now() + 10ms;
for (;;)
{
this_thread::sleep_until(t0);
t0 += 10ms;
}
}
Можно одеть это с большим количеством вызовов steady_clock::now()
, чтобы определить время между итерациями, и, возможно, что еще более важно, среднее время итерации:
#include <chrono>
#include <iostream>
#include <thread>
int
main()
{
using namespace std;
using namespace std::chrono;
using dsec = duration<double>;
auto t0 = steady_clock::now() + 10ms;
auto t1 = steady_clock::now();
auto t2 = t1;
constexpr auto N = 1000;
dsec avg{0};
for (auto i = 0; i < N; ++i)
{
this_thread::sleep_until(t0);
t0 += 10ms;
t2 = steady_clock::now();
dsec delta = t2-t1;
std::cout << delta.count() << "s\n";
avg += delta;
t1 = t2;
}
avg /= N;
cout << "avg = " << avg.count() << "s\n";
}
Выше я добавил к издержкам цикла, делая больше вещей в цикле. Однако цикл все еще будет просыпаться около каждые 10 мс. Иногда ОС просыпает поток поздно, но в следующий раз цикл автоматически настраивается на более короткий период сна. Таким образом, средняя скорость итерации автоматически корректируется до 10 мс.
На моей машине это просто вывод:
...
0.0102046s
0.0128338s
0.00700504s
0.0116826s
0.00785826s
0.0107023s
0.00912614s
0.0104725s
0.010489s
0.0112545s
0.00906409s
avg = 0.0100014s