Windows上的UTC时间戳

时间:2010-05-18 10:14:18

标签: c windows

我有一个带有UTC时间戳的缓冲区,我每十秒钟就会播放一次缓冲区。问题是两个数据包之间的时差不一致。经过5到10次迭代后,时差变为9,11,然后再次为10.请帮助我解决这个问题。

我正在使用<time.h>作为UTC时间。

2 个答案:

答案 0 :(得分:3)

如果你的时间戳只有1秒的分辨率,那么最低有效数字总是会有+/- 1的不确定性(在这种情况下是+/- 1秒)。

澄清:如果您只有1秒的分辨率,那么您的时间值为quantized。由这样的量化值表示的实时t具有t..t+0.9999的范围。如果你取两个这样的时间差t0t1,则t1-t0中的最大误差为-0.999..+0.999,量化后的+/-1秒。因此,在您的情况下,您可能会看到9..11秒范围内的差值。

答案 1 :(得分:1)

睡眠时间为X毫秒的线程无法保证正好睡眠很多毫秒。我假设你的陈述类似于:

while(1) {
  ...
  sleep(10); // Sleep for 10 seconds.
  // fetch timestamp and send
}

如果您在循环检查中睡眠时间较短(比如20毫秒),您将获得更准确的时间表,直到时间结束。当您休眠10秒钟时,您的线程会进一步移出基础操作系统的即时调度优先级。

您还可以考虑发送时间戳所花费的时间可能会有所不同,具体取决于网络状况等,如果你睡觉(10) - > send - &gt; sleep(10)类型的循环,发送时间将实际添加到下一次睡眠(10)。

尝试这样的事情(原谅我,我的C有点生锈):

bool expired = false;
double last, current;
double t1, t2;
double difference = 0;

while(1) {
   ...
   last = (double)clock();
   while(!expired) {
      usleep(200); // sleep for 20 milliseconds
      current = (double)clock();
      if(((current - last) / (double)CLOCKS_PER_SEC) >= (10.0 - difference))
        expired = true;
   }
   t1 = (double)clock();
   // Set and send the timestamp.
   t2 = (double)clock();
   //
   // Calculate how long it took to send the stamps.
   // and take that away from the next sleep cycle.
   //
   difference = (t2 - t1) / (double)CLOCKS_PER_SEC;
   expired = false;
 }

如果您不打算使用标准C库,可以考虑使用Windows的高分辨率计时器功能,例如QueryPerformanceFrequency / QueryPerformanceCounter函数。

LONG_INTEGER freq;
LONG_INTEGER t2, t1;
//
// Get the resolution of the timer.
//
QueryPerformanceFrequency(&freq);

// Start Task.
QueryPerformanceCounter(&t1);

... Do something ....

QueryPerformanceCounter(&t2);

// Very accurate duration in seconds.
double duration = (double)(t2.QuadPart - t1.QuadPart) / (double)freq.QuadPart;