这是我使用QueryPeformanceCounter
作为计时器的代码。
//timer.h
class timer {
private:
...
public:
...
double get(); //returns elapsed time in seconds
void start();
};
//a.cpp
void loop() {
timer t;
double tick;
double diff; //surplus seconds
t.start();
while( running ) {
tick = t.get();
if( tick >= 1.0 - diff ) {
t.start();
//things that should be run exactly every second
...
}
Sleep( 880 );
}
}
如果没有Sleep
,这个循环会每次无限期地调用t.get()
,这会导致高CPU使用率。出于这个原因,我让它睡了大约880毫秒,这样就不会在没有必要的情况下调用t.get()
。
正如我上面所说,我目前正在使用Sleep
来解决问题,但我担心的是Sleep
的准确性。我在某处读到程序暂停的实际毫秒数可能会有所不同 - 20到50毫秒 - 我将参数设置为880
的原因。我想尽可能地减少CPU使用率;我希望,如果可能的话,在每个循环之间暂停超过990毫秒编辑:但小于1000毫秒。什么是最好的方式?
答案 0 :(得分:0)
我不明白为什么你要两次调用t.start()
(它重置时钟?),但我想提出一种Sleep
不准确的解决方案。我们来看看while( running )
循环的内容并遵循算法:
double future, remaining, sleep_precision = 0.05;
while (running) {
future = t.get() + 1.0;
things_that_should_be_run_exactly_every_second();
// the loop in case of spurious wakeup
for (;;) {
remaining = future - t.get();
if (remaining < sleep_precision) break;
Sleep(remaining);
}
// next, do the spin-lock for at most sleep_precision
while (t.get() < future);
}
sleep_precision
的值应该根据经验设定 - 我认识的操作系统不能给你这个。
接下来,有一些替代的睡眠机制可能更适合您的需求 - Is there an alternative for sleep() in C?
答案 1 :(得分:-1)
如果要暂停超过990毫秒,请写入休眠991毫秒。你的线程保证至少在那么长时间内睡着了。它不会少,但它可能是20-50ms 更多的倍数(取决于操作系统时间切片的分辨率,以及上下文切换的成本)。
然而,这不会给你“正好每一秒”运行的东西。在分时操作系统上无法实现这一点。您必须更接近金属编程,或依赖PPS源的中断,并祈祷您的操作系统允许您一次性运行整个循环迭代。或者,我想,写一些在内核模式下运行的东西......?