Windows 上的 UTC 时间戳 [英] UTC time stamp on Windows
问题描述
我在 C 中有一个带有 UTC 时间戳的缓冲区,我每十秒广播一次该缓冲区.问题是两个数据包的时间差不一致.经过 5 到 10 次迭代后,时间差变为 9、11 和 10.请帮助我解决这个问题.
I have a buffer with the UTC time stamp in C, I broadcast that buffer after every ten seconds. The problem is that the time difference between two packets is not consistent. After 5 to 10 iterations the time difference becomes 9, 11 and then again 10. Kindly help me to sort out this problem.
我使用
作为 UTC 时间.
I am using <time.h>
for UTC time.
推荐答案
休眠 X 毫秒的线程并不能保证休眠精确到那么多毫秒.我假设您有一个类似于以下内容的声明:
A thread that sleeps for X milliseconds is not guaranteed to sleep for precisely that many milliseconds. I am assuming that you have a statement that goes something like:
while(1) {
...
sleep(10); // Sleep for 10 seconds.
// fetch timestamp and send
}
如果您在循环检查中睡眠时间较短(例如 20 毫秒),直到时间到期,您将获得更准确的时间计量.当您休眠 10 秒时,您的线程会进一步脱离底层操作系统的即时调度优先级.
You will get a more accurate gauge of time if you sleep for shorter periods (say 20 milliseconds) in a loop checking until the time has expired. When you sleep for 10 seconds, your thread gets moved further out of the immediate scheduling priority of the underlying OS.
您可能还考虑到发送时间戳所花费的时间可能会有所不同,具体取决于网络条件等,如果您执行 sleep(10) -> send ->sleep(10) 类型的循环,则时间采取发送将实际添加到下一个睡眠(10).
You might also take into account that the time taken to send the timestamps may vary, depending on network conditions, etc, if you do a sleep(10) -> send ->sleep(10) type of loop, the time taken to send will be added onto the next sleep(10) in real terms.
试试这样的东西(原谅我,我的 C 有点生疏):
Try something like this (forgive me, my C is a little rusty):
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 函数.
If you are not bothered about using the standard C library, you could look at using the high resolution timer functionality of windows such as QueryPerformanceFrequency/QueryPerformanceCounter functions.
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;
这篇关于Windows 上的 UTC 时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!