Poniższy fragment kodu:
struct timespec ts;
for (int x = 0; x < 100000000; x++) {
timespec_get(&ts, TIME_UTC);
long cTime = (long) time(NULL);
if (cTime != ts.tv_sec && ts.tv_nsec < 3000000) {
printf("cTime: %ld\n", cTime);
printf("ts.tv_sec: %ld\n", ts.tv_sec);
printf("ts.tv_nsec: %ld\n", ts.tv_nsec);
}
}
tworzy ten wynik:
...
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2527419
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2534036
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2540359
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2547039
...
Dlaczego rozbieżność między cTime
i ts.tv_sec
? Zauważ, że problem nie występuje, jeśli zmienna warunkowa zostanie zmieniona na ts.tv_nsec >= 3000000
. Problem polega na tym, że nanosekundy są mniejsze niż 3000000.
timespec_get()
? Czy to C czy C ++? Wyglądastd::timespec_get
. Proszę użyć odpowiedniego tagu.man
wpisutimespec_get
w moim systemie, więc doszedłem do wniosków. Ma sens.Odpowiedzi:
Powodem jest to, że (domyślnie) używasz różnych zegarów systemowych.
timespec_get()
wykorzystuje wysokiej rozdzielczości zegara czasu rzeczywistego dla całego systemu, atime()
Używa gruba zegar czasu rzeczywistego.Spróbuj użyć
zamiast twojego
timespec_get()
, różnica powinna zniknąć.Edytować:
Można to zobaczyć w Linux Kernel Source, vclock_gettime.c
Rzeczywiście problem ten jest nieco subtelny. Część sekundowa elementów konstrukcji używana przez
CLOCK_REALTIME_COARSE
iCLOCK_REALTIME
zawiera identyczne wartości, ale część nanosekundowa jest inna; zCLOCK_REALTIME
tym może być większy niż1000000000
(co jest jedną sekundą). W takim przypadku jest ustalone na połączenie:Ta korekta nie jest wykonywana ani za pomocą
CLOCK_REALTIME_COARSE
, ani za pomocątime()
. To wyjaśnia różnicę międzyCLOCK_REALTIME
itime()
.źródło
time
implementacji z (przypuszczalnie) bardziej wydajnym, ale mniej dokładnym zegarem (zgodnie z teorią, że i tak ma tylko drugą ziarnistość, więc kto potrzebuje precyzji)? Opóźnianie w czasie rzeczywistym o około milisekundę (testy online wykazały sporadyczne opóźnienie powyżej ms, ale niewiele więcej), gdy tylko pytasz o drugą ziarnistość, nie wydaje się tak ważne.