Функция this_thread::sleep_until
Функция this_thread::sleep_until приостанавливает
выполнение текущего потока до наступления момента времени,
переданного в параметре. В первый параметр мы передаем
момент времени, до которого следует приостановить поток.
Функция объявлена в заголовочном файле <thread>
и находится в пространстве имен std::this_thread.
В отличие от функции sleep_for, которая принимает
длительность паузы, функция sleep_until принимает
абсолютную точку во времени. Это удобно, когда нужно
дождаться конкретного момента, например, начала следующей
секунды или заданного времени суток.
Если указанный момент времени уже наступил к моменту вызова, функция возвращает управление немедленно. В противном случае поток блокируется до наступления этого момента.
Синтаксис
namespace std::this_thread {
template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& sleep_time);
}
Пример
Давайте приостановим поток на 2 секунды, вычислив
момент времени как текущее время плюс длительность:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main()
{
auto start = chrono::steady_clock::now();
this_thread::sleep_until(start + chrono::seconds(2));
auto end = chrono::steady_clock::now();
auto elapsed = chrono::duration_cast<chrono::milliseconds>(end - start).count();
cout << "Elapsed: " << elapsed << " ms" << endl;
return 0;
}
Результат выполнения кода:
"Elapsed: 2000 ms"
Пример
Давайте приостановим поток до наступления конкретного
момента времени, заданного через system_clock:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main()
{
auto now = chrono::system_clock::now();
auto target = now + chrono::milliseconds(500);
this_thread::sleep_until(target);
auto after = chrono::system_clock::now();
auto diff = chrono::duration_cast<chrono::milliseconds>(after - target).count();
cout << "Woke up after target by: " << diff << " ms" << endl;
return 0;
}
Результат выполнения кода:
"Woke up after target by: 0 ms"
Пример
Давайте организуем цикл, выполняющийся каждые 100
миллисекунд, используя sleep_until для точного
планирования:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main()
{
auto next = chrono::steady_clock::now();
for (int i = 0; i < 3; i++) {
next += chrono::milliseconds(100);
this_thread::sleep_until(next);
cout << "Tick " << i << endl;
}
return 0;
}
Результат выполнения кода:
"Tick 0"
"Tick 1"
"Tick 2"