实现高分辨率计时器的最佳方法
Best way to implement a high resolution timer
在 C++11 中实现高分辨率计时器的最佳方法是什么,该计时器连续检查循环中的时间,并在经过某个时间点后执行一些代码? 例如,从上午 9 点开始检查它在循环中的时间,并在上午 11 点准确执行一些代码。我要求时间精确(即上午 9 点后不超过 1 微秒(。
我将在 Linux CentOS 7.3 上实现此程序,并且将 CPU 资源用于执行此任务没有任何问题。
您可以使用例如systemd.timer
代替手动实现它。确保指定所需的精度,该精度显然可以精确到1us。
高分辨率计时器,可以连续检查循环中的时间,
首先,你不想在一个循环中连续检查时间;这是非常低效的,而且完全没有必要。
。在经过某个时间点后执行一些代码?
好的,所以您希望在将来的给定时间尽可能准确地运行一些代码。
最简单的方法是简单地启动后台线程,计算距离目标时间(以所需分辨率(的时间,然后将线程置于该时间段的睡眠状态。当线程唤醒时,它会执行实际任务。这应该足够准确,可以满足绝大多数需求。
std::chrono
库提供的调用使这变得简单:
- 系统时钟输入
std::chrono
- 高分辨率时钟输入
std::chrono
下面是一段代码,它使用系统时钟执行您想要的操作(这样可以更轻松地设置挂钟时间(:
// c++ --std=c++11 ans.cpp -o ans
#include <thread>
#include <iostream>
#include <iomanip>
// do some busy work
int work(int count)
{
int sum = 0;
for (unsigned i = 0; i < count; i++)
{
sum += i;
}
return sum;
}
std::chrono::system_clock::time_point make_scheduled_time (int yyyy, int mm, int dd, int HH, int MM, int SS)
{
tm datetime = tm{};
datetime.tm_year = yyyy - 1900; // Year since 1900
datetime.tm_mon = mm - 1; // Month since January
datetime.tm_mday = dd; // Day of the month [1-31]
datetime.tm_hour = HH; // Hour of the day [00-23]
datetime.tm_min = MM;
datetime.tm_sec = SS;
time_t ttime_t = mktime(&datetime);
std::chrono::system_clock::time_point scheduled = std::chrono::system_clock::from_time_t(ttime_t);
return scheduled;
}
void do_work_at_scheduled_time()
{
using period = std::chrono::system_clock::period;
auto sched_start = make_scheduled_time(2019, 9, 17, // date
00, 14, 00); // time
// Wait until the scheduled time to actually do the work
std::this_thread::sleep_until(sched_start);
// Figoure out how close to scheduled time we actually awoke
auto actual_start = std::chrono::system_clock::now();
auto start_delta = actual_start - sched_start;
float delta_ms = float(start_delta.count())*period::num/period::den * 1e3f;
std::cout << "worker: awoken within " << delta_ms << " ms" << std::endl;
// Now do some actual work!
int sum = work(12345);
}
int main()
{
std::thread worker(do_work_at_scheduled_time);
worker.join();
return 0;
}
在我的笔记本电脑上,典型的延迟约为 2-3 毫秒。如果您使用high_resolution_clock
,您应该能够获得更好的结果。
您还可以使用其他API,例如Boost,您可以在其中使用ASIO来实现高分辨率超时。
我要求时间精确(即上午 9 点后不超过 1 微秒(。
你真的需要它精确到微秒吗?考虑到在此分辨率下,您还需要考虑各种其他因素,包括系统负载、延迟、时钟抖动等。您的代码可以在接近该时间开始执行,但这只是问题的一部分。
我的建议是使用 timer_create((。这允许您在给定时间收到信号通知。然后,您可以在信号处理程序中实现您的操作。
在任何情况下,您都应该知道,准确性当然取决于系统时钟的准确性。
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 检测win32服务创建和删除的最佳方法
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 将线程中的数据存储到全局容器的最佳方法?
- 将一系列整数放入类的最佳方法是什么?
- 在派生类中使用基类的私有成员变量的最佳方法
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 比较两个节点坐标的最佳方法是什么?
- 在nodejs中使用本机代码的最佳方法是什么?
- 将 pybind11 绑定标记为已弃用的最佳方法
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?