我正在写一个检查点。我每次运行循环时都会检查。我认为这会浪费大量的CPU时间。我想知道如何每隔10秒检查系统时间?
time_t start = clock();
while(forever)
{
if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit)
{
break;
}
}
答案 0 :(得分:9)
如果您是新手程序员,那么非常简短的答案就是非常困难。
现在有几个可能性:
睡眠十秒钟。这意味着你的程序基本没有意义。
使用alarm()
和信号处理程序。这很难做到,因为你不能在信号处理程序中做任何花哨的事情。
使用timerfd
并将时序逻辑集成到I / O循环中。
为计时器设置专用线程(然后可以休眠);这非常困难,因为您需要考虑同步所有共享数据访问。
这里带回家的重点是你的问题没有一个简单的解决方案。您需要将时序逻辑深入地集成到现有的程序流程中。这个流应该是某种“主循环”(例如像epoll_wait
或select
的I / O复用循环),可能是多线程的,并且该循环应该发现定时器具有的事实烧成。
这并不容易。
这是一个切线,可能是有启发性的。基本上有两种计算机程序(除了所有其他类型):
一种是尽可能有效地执行一项特定任务的程序,然后完成。例如,这类似于“生成SSL密钥对”或“查找文件中与X匹配的所有行”。就程序流程而言,这些程序易于编写和理解。
另一种是与用户交互的程序。这些程序无限期地保持不变并响应用户输入。 (基本上是任何类型的UI或游戏,但也是一个Web服务器。)从控制流的角度来看,这些程序花费大部分时间来做...... nothing 。他们只是空闲等待用户输入。因此,当您考虑如何编程时,如何使程序无所作为?这是“主循环”的核心:它是一个循环,告诉操作系统让进程保持睡眠直到发生一些有趣的事情,然后处理有趣的事件,然后再回到睡眠状态。
直到你明白如何做 nothing ,你才能设计出第二种程序。
答案 1 :(得分:3)
如果需要精度,可以使用null参数调用select()但有延迟。这精确到毫秒。
struct timeval timeout= {10, 0};
select(1,NULL,NULL,NULL, &timeout);
如果不这样做,只需使用sleep():
sleep(10);
答案 2 :(得分:0)
只需添加对sleep的调用即可为系统提供CPU时间:
time_t start = clock();
while(forever)
{
if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit)
{
break;
}
sleep(1); // <<< put process to sleep for 1s
}
答案 3 :(得分:0)
您可以在程序中使用事件循环并安排计时器进行回调。 For example您可以使用libev制作事件循环并添加计时器。
ev_timer_init (timer, callback, 0., 5.);
ev_timer_again (loop, timer);
...
timer->again = 17.;
ev_timer_again (loop, timer);
...
timer->again = 10.;
ev_timer_again (loop, timer);
如果你在特定的工具包中编码,你可以使用其他事件循环,gtk,qt,glib有自己的事件循环,所以你可以使用它们。
答案 4 :(得分:0)
最简单的方法(在单线程环境中),将睡眠一段时间并反复检查总等待时间是否已过期。
int sleepPeriodMs = 500;
time_t start = clock();
while(forever)
{
while(difftime(clock(),start)/CLOCKS_PER_SEC <timeLimit) // NOTE: Change of logic here!
{
sleep(sleepPeriod);
}
}
请注意,sleep()
不是很准确。如果您需要更高精度的时序(即优于10ms的分辨率),您可能需要深入挖掘。此外,使用C ++ 11,<chrono>
标头提供了更多功能。
using namespace std::chrono;
int sleepPeriodMs = 500;
time_t start = clock();
while(forever)
{
auto start = system_clock()::now()
// do some stuff that takes between [0..10[ seconds
std::this_thread::sleep_until(start+seconds(10));
}