较长的睡眠(使用C++)比较短的睡眠时间更短

NoS*_*tAl 17 c++ boost sleep

我有一个任务,每隔"圆"分钟做一些事情(在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年被激活.但我问的是现实场景.

Yoc*_*mer 7

当您进入睡眠状态(N)时,它会告诉操作系统在当前时间+ N触发线程.

它并不总是准确的原因是你不是系统中唯一的线程.
在你之前可能还有另一个要求被唤醒的线程,并且可能只有一些重要的操作系统内容需要在那时完成.

无论如何,应该没有任何精度问题,因为该方法与N无关.

它不是"精确"的唯一原因是它是一个糟糕的操作系统无法正确计算时间.然后,循环将无法解决这个问题.

  • 是的,因为如果积累了错误. (2认同)
  • "当您进入睡眠状态(N)时,它会告诉操作系统在当前时间+ N触发线程." 更准确地说,OS不早于"时间+ N"触发线程.允许任意触发线程,但从不提前. (2认同)

bdo*_*lan 7

在一些线程API中,可以睡眠完成之前唤醒(例如,由于在睡眠期间到达的信号).处理此问题的正确方法是计算绝对唤醒时间,然后循环,在剩余持续时间内休眠.我会想象以一秒的间隔睡觉是一个黑客来近似这个,很糟糕.

但是,this_thread::sleep()没有记录提升线程API 有这些早期的唤醒,因此这种技术不是必需的(boost thread API为你做了循环).

一般来说,使用较小的睡眠间隔可以显着改善唤醒延迟的情况非常少; 操作系统或多或少地以相同的方式处理所有唤醒.充其量,您可以保持缓存温暖并避免页面调度,但这只会影响直接参与睡眠循环的一小部分内存.

此外,大多数操作系统在内部使用整数计数器处理时间; 这意味着较大的间隔不会导致舍入错误(正如您可能会发现浮点值).但是,如果使用浮点进行自己的计算,这可能是一个问题.如果您当前正在使用浮点间隔(例如,double自1970年以来的秒数),您可能希望考虑整数单位(例如,long long自1970年以来的毫秒数).