Der folgende Codeausschnitt:
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);
}
}
erzeugt diese Ausgabe:
...
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
...
Warum die Diskrepanz zwischen cTime
und ts.tv_sec
? Beachten Sie, dass das Problem nicht auftritt, wenn die Bedingung in geändert wird ts.tv_nsec >= 3000000
. Das Problem beruht darauf, dass Nanosekunden kleiner als 3000000 sind.
timespec_get()
? Ist das C oder C ++? Sieht aus wiestd::timespec_get
. Bitte verwenden Sie das entsprechende Tag.man
Eintrag fürtimespec_get
auf meinem System sehen, also bin ich zu Schlussfolgerungen gesprungen. Macht Sinn.Antworten:
Der Grund ist, dass Sie (implizit) verschiedene Systemuhren verwenden.
timespec_get()
verwendet die hochauflösende systemweite Echtzeituhr, währendtime()
die grobe Echtzeituhr verwendet wird.Versuchen zu benutzen
Anstelle von dir
timespec_get()
sollte der Unterschied verschwinden.Bearbeiten:
Dies ist in der Linux-Kernel-Quelle vclock_gettime.c zu sehen
In der Tat ist das Problem hier etwas subtil zu sehen. Der Sekunden-Teil der Strukturelemente, die von identischen Werten verwendet werden
CLOCK_REALTIME_COARSE
und dieseCLOCK_REALTIME
enthalten, aber der Nanosekunden-Teil ist unterschiedlich. mitCLOCK_REALTIME
kann sie größer sein als1000000000
(die eine Sekunde). In diesem Fall wird es beim Anruf behoben:Diese Korrektur wird weder mit
CLOCK_REALTIME_COARSE
noch mit durchgeführttime()
. Dies erklärt den Unterschied zwischenCLOCK_REALTIME
undtime()
.quelle
time
Implementierung mit der (vermutlich) leistungsfähigeren, aber weniger genauen Uhr (nach der Theorie, dass es sowieso nur eine zweite Granularität gibt, also wer braucht Präzision)? Eine Verzögerung von etwa einer Millisekunde in Echtzeit (Online-Tests zeigten eine gelegentliche Verzögerung von mehr als einer ms, aber nicht viel mehr), wenn Sie nur nach einer zweiten Granularität fragen, ist wohl nicht so wichtig.