准确的花时间解决方案

时间:2014-02-25 07:42:35

标签: java c++ c multithreading pthreads

考虑以下代码段

class time implement Runnable{
 long t=0L;
 public void run(){
  try{while(true){Thread.sleep(1000);t++;/*show the time*/}}catch(Throwable t){}
 }
}

////

long long t=0L;
void* time(void* a){//pthread thread start
sleep(1);t++;//show the time
}

我在一些教程中读到,在Java Thread.sleep(1000)中并不完全是1秒,如果系统当时处于忙碌状态可能会更多,那么操作系统会更晚地切换到该线程。
/> 问题:
这种情况是真的还是没有?
这种情况对于原生(C/C++)代码是否相同? 计算应用程序中秒数的准确方法是什么?

6 个答案:

答案 0 :(得分:2)

回答以下两个问题:是的,这是真的,是的。

首先是超时到期和操作系统注意到它之间的时间,然后是操作系统重新安排进程的时间,最后是从进程被“唤醒”直到它的时间轮到跑了。这需要多长时间?没有办法说。

由于这一切都是在操作系统级别完成的,因此您编写的语言并不重要。

至于更准确的方式?空无一人。您可以使用更高精度的计时器,但无法避免上述延迟。

答案 1 :(得分:2)

其他人已经回答了时间的准确性。不幸的是,没有保证的方式在X时间内睡眠,并且正好在X.00000秒(或毫秒,纳秒等)唤醒。

以秒为单位显示时间,您可以降低等待时间,例如半秒。然后你不会有时间跳两秒钟,因为半秒不会延长到一秒以上(除非您运行的操作系统和系统绝对超载并且没有任何内容它应该运行 - 在这种情况下你应该解决这个问题[获得更快的处理器,更多的内存,或任何它需要],而不是摆弄你的应用程序的时间)。这适用于“相对长的时间段”,例如一秒或十分之一秒。为了获得更高的精度,它不会真正起作用,因为我们现在正在进入“调度抖动”区域。

如果你想要非常精确的计时,那么你可能需要使用实时操作系统,或者至少是一个启用了“实时扩展”的操作系统,这将使操作系统对时间更加严格(在程序员的“易用性”成本,以及操作系统处理流程的效率可能较低,因为与更“懒惰”的计时方法相比,它“更频繁地切换”。

另请注意,“可能需要更长时间”,在空闲系统中主要是“计时器的四舍五入”(如果系统标记每10ms或1ms发生一次,则计时器设置为1000ms +剩下的任何剩余的当前计时器刻度,因此可能是1009.999ms,或1000.75ms。另外一个来自调度和一般操作系统开销的开销应该在微秒范围内(如果不是纳秒)在任何现代系统上 - 毕竟,操作系统可以在一微秒内完成相当多的工作 - 现代x86 CPU将执行3个周期每个时钟,时钟大约0.3ns。这是每纳秒10条指令[当然,缓存未命中等会使这种情况恶化]。如果操作系统有超过几千个指令从一个进程转到另一个进程(对于线程来说更少),那么就有一些错误。几千条指令@每条纳秒的10条指令=几百纳秒。绝对不到一微秒。将其与上次定时器关闭后启动定时器的1ms或10ms“抖动”进行比较。

当然,如果CPU忙于运行其他任务,这是不同的 - 那么其他进程的“剩余运行”时间也会影响唤醒进程所需的时间。

当然,在负载很重的内存系统中,“刚刚唤醒”进程可能不会“准备好运行”,例如,它可以被换出到磁盘。在这种情况下,需要几十到几百毫秒才能从磁盘加载它。

答案 2 :(得分:1)

是的,确实不准确 对于C / C ++中的简单睡眠功能以及其他所有内容,它都是一样的 根据您的系统,可以使用更好的功能,
但是:

  

准确的方法

不存在真正准确的方法 Unles你有一些非常昂贵的特殊电脑,包括原子钟 (并且没有通常的操作系统。即便如此,我们也可以争论“准确”意味着什么)

如果忙碌等待(高CPU负载)可以接受,请查看nanoTime或本机usleep,HighPerformanceCounter或适用于您系统的任何内容

答案 3 :(得分:1)

sleep调用告诉系统至少在指定为参数的时间段内停止线程执行。然后,系统将在有机会时恢复线程执行(实际上它取决于许多因素,例如硬件,线程优先级等)。或多或少地精确测量您可以在执行开始时存储时间的时间,然后在每次需要时计算时间增量。

答案 4 :(得分:1)

睡眠功能不准确,但如果意图是显示总秒数,则应将当前时间存储在开头,然后不时显示时差。

答案 5 :(得分:1)

这是事实。任何语言(sleep)中的每个C实现都将无法等待1秒钟。它必须处理你的操作系统调度程序,睡眠持续时间是一个提示:the minimum sleep duration准确,但实际的差异取决于千兆因素。

如果你想要一个非常高分辨率的时钟,试图找出偏差是很棘手的。在大多数情况下,你会有大约1~5毫秒(大致)。

事情是,无论睡眠持续时间如何,数量级都是相同的。如果你想要“准确”的东西,你可以划分时间申请并等待更长的时间。例如,当您进行基准测试时,您会更喜欢这种类型的实现,因为增量时间会增加,从而降低不确定性:

// get t0
// process n times
// get t1    
// compute average time : (t1-t0)/n