2010-05-18 2 views
1

У меня есть буфер с отметкой времени UTC в C, я транслирую этот буфер каждые десять секунд. Проблема в том, что разница во времени между двумя пакетами не является последовательной. После 5-10 итераций разница во времени становится 9, 11, а затем снова 10. Просьба помочь мне разобраться в этой проблеме.UTC штамп времени на Windows

Я использую <time.h> для UTC.

+0

Я не уверен, в чем проблема. Вы спите 10 секунд, чтобы получить время и найти разницу не всегда 10 секунд? – Artefacto

+0

Да, мой поток в течение 10 секунд после этого снова получает время UTC и отправляет. – Siddiqui

ответ

1

Нить, которая спит в течение X миллисекунд, не гарантирует спать ровно столько миллисекунд. Я предполагаю, что у вас есть заявление, что идет что-то вроде:

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

Вы получите более точную меру времени, если вы спите на более короткие периоды (скажем 20 миллисекунд) в цикле проверки, пока время не истекло. Когда вы спите в течение 10 секунд, ваш поток перемещается дальше от приоритета немедленного планирования базовой ОС.

Вы также можете учесть, что время, затрачиваемое на отправку меток времени, может меняться в зависимости от условий сети и т. Д., Если вы выполняете тип цикла (10) -> send -> 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, вы можете посмотреть с помощью функции таймера высокого разрешения таких как 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; 
+1

P.S. Вы можете использовать что-то более точное, чем difftime, так как это разрешение составляет 1 секунду. something clock() с константой CLK_PER_SECOND. –

+0

Доступен ли CLOCK_PER_SECOND для окон? – Siddiqui

+1

Да, это часть стандартной библиотеки c. CLOCKS_PER_SEC. Чтобы получить более точное время, читайте двойной t = (dobule) clock()/(double) CLOCKS_PER_SEC; –

3

Если ваша метка времени имеет разрешение только 1 секунду, тогда всегда будет неопределенность +/- 1 в наименее значащей цифре (то есть +/- 1 секунду в этом случае).

Уточнение: если у вас есть разрешение 1 секунда, тогда ваши значения времени: quantized. В реальном времени t, представленное таким квантованным значением, имеет диапазон t..t+0.9999. Если вы принимаете разницу в два таких раза: t0 и t1, тогда максимальная ошибка в t1-t0 равна -0.999..+0.999, которая при квантовании равна +/-1 секунд. Поэтому в вашем случае вы ожидаете увидеть разностные значения в диапазоне 9..11 секунд.

+0

Пожалуйста, объясните мне, что вы подразумеваете под разрешением 1 секунду? И как я могу решить эту проблему. – Siddiqui

+0

@Arman: см. Выше для дальнейшего объяснения. –

Смежные вопросы