我有一个任务,每隔"圆"分钟做一些事情(在xx:xx:00)我使用类似的东西
const int statisticsInterval=60;
time_t t=0;
while (1)
{
if (abs(t-time(NULL)==0)) //to avoid multiple calls in the same second that is the multiple of 60
boost::this_thread::sleep(boost::posix_time::seconds(2));//2, not 1 to make sure that 1 second passes
t=time(NULL);
boost::this_thread::sleep(boost::posix_time::seconds(statisticsInterval-(t%statisticsInterval)));
//DO WORK
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我使用睡眠(60秒 - 当前分钟经过的秒数).但是一位程序员告诉我,这不准确,我应该把它改成while while while while sleep(1).我认为他是对的非常怀疑,但我只是想检查是否有人知道如果睡眠间隔很长,精度是否较低.我假设睡眠是以一种方式实现的,即在将来触发器被激活并且线程被置于"准备执行线程组"的某个时间,所以我认为没有理由精确地使用diff.BTW OS是ubuntu,我不关心不到2-3秒的错误.例如,如果我睡了52秒,53.8睡眠是完全可以接受的.PS我知道睡眠定义的最短时间,理论上我的线程可能会在2047年被激活.但我问的是现实场景.
当您进入睡眠状态(N)时,它会告诉操作系统在当前时间+ N触发线程.
它并不总是准确的原因是你不是系统中唯一的线程.
在你之前可能还有另一个要求被唤醒的线程,并且可能只有一些重要的操作系统内容需要在那时完成.
无论如何,应该没有任何精度问题,因为该方法与N无关.
它不是"精确"的唯一原因是它是一个糟糕的操作系统无法正确计算时间.然后,循环将无法解决这个问题.
在一些线程API中,可以在睡眠完成之前唤醒(例如,由于在睡眠期间到达的信号).处理此问题的正确方法是计算绝对唤醒时间,然后循环,在剩余持续时间内休眠.我会想象以一秒的间隔睡觉是一个黑客来近似这个,很糟糕.
但是,this_thread::sleep()没有记录提升线程API 有这些早期的唤醒,因此这种技术不是必需的(boost thread API为你做了循环).
一般来说,使用较小的睡眠间隔可以显着改善唤醒延迟的情况非常少; 操作系统或多或少地以相同的方式处理所有唤醒.充其量,您可以保持缓存温暖并避免页面调度,但这只会影响直接参与睡眠循环的一小部分内存.
此外,大多数操作系统在内部使用整数计数器处理时间; 这意味着较大的间隔不会导致舍入错误(正如您可能会发现浮点值).但是,如果您使用浮点进行自己的计算,这可能是一个问题.如果您当前正在使用浮点间隔(例如,double自1970年以来的秒数),您可能希望考虑整数单位(例如,long long自1970年以来的毫秒数).
| 归档时间: |
|
| 查看次数: |
1842 次 |
| 最近记录: |