O seguinte trecho de código:
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);
}
}
produz esta saída:
...
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
...
Por que a discrepância entre cTime
e ts.tv_sec
? Observe que o problema não ocorre se a condicional for alterada para ts.tv_nsec >= 3000000
. O problema depende dos nanossegundos serem menores que 3000000.
timespec_get()
? Isso é C ou C ++? Parece que simstd::timespec_get
. Por favor, use a etiqueta apropriada.man
entradatimespec_get
no meu sistema, então tirei conclusões precipitadas. Faz sentido.Respostas:
O motivo é que você (implicitamente) usa diferentes relógios do sistema.
timespec_get()
usa o relógio em tempo real de alta resolução em todo o sistema, enquantotime()
usa o relógio em tempo real aproximado .Tente usar
em vez de você
timespec_get()
, a diferença deve desaparecer.Editar:
Isso pode ser visto na fonte do kernel do Linux, vclock_gettime.c
De fato, a questão é um pouco sutil de se ver aqui. A parte dos segundos dos membros da estrutura usada por
CLOCK_REALTIME_COARSE
eCLOCK_REALTIME
contém valores idênticos, mas a parte dos nanossegundos é diferente; comCLOCK_REALTIME
ele pode ser maior que1000000000
(que é um segundo). Nesse caso, é corrigido na chamada:Esta correção não é realizada com
CLOCK_REALTIME_COARSE
, nem comtime()
. Isso explica a diferença entreCLOCK_REALTIME
etime()
.fonte
time
ser implementado com o (presumivelmente) relógio com melhor desempenho, mas menos preciso (na teoria de que ele só tem segunda granularidade de qualquer maneira, então quem precisa de precisão)? Atrasar o tempo real em um milissegundo mais ou menos (testes on-line mostraram um atraso ocasional de mais de um ms, mas não muito mais) quando você está apenas pedindo uma segunda granularidade não é tão importante, eu acho.