Você poderia explicar a diferença entre CLOCK_REALTIME
e os CLOCK_MONOTONIC
relógios retornados clock_gettime()
no Linux?
Qual é a melhor opção se eu precisar calcular o tempo decorrido entre os carimbos de data e hora produzidos por uma fonte externa e o horário atual?
Por fim, se eu tenho um daemon NTP ajustando periodicamente a hora do sistema, como esses ajustes interagem com cada um deles CLOCK_REALTIME
e CLOCK_MONOTONIC
?
CLOCK_MONOTONIC
a melhor escolha nesse cenário? por exemplo, Patriot Missile SystemO livro de Robert Love, LINUX System Programming 2nd Edition , aborda especificamente sua pergunta no início do capítulo 11, página 363:
Dito isso, acredito que ele esteja assumindo que os processos estão em execução na mesma instância de um sistema operacional; portanto, convém executar uma calibração periódica para estimar a deriva.
fonte
CLOCK_REALTIME
é afetado pelo NTP e pode se mover para frente e para trás.CLOCK_MONOTONIC
não é, e avança em um tick por tick.fonte
System.nanoTime()
usaCLOCK_MONOTONIC
e pode medir durações de 1000ns ou menos. Talvez você esteja pensando na hora do sistema, que às vezes é limitada a milissegundos?Além da resposta de Ignacio ,
CLOCK_REALTIME
pode avançar em saltos e, ocasionalmente, para trás.CLOCK_MONOTONIC
não faz; ele continua avançando (embora provavelmente seja redefinido na reinicialização).Um aplicativo robusto precisa ser capaz de tolerar
CLOCK_REALTIME
saltar para a frente ocasionalmente (e talvez para trás muito ligeiramente, muito ocasionalmente, embora isso seja mais um exemplo de caso).Imagine o que acontece quando você suspende o laptop -
CLOCK_REALTIME
salta para a frente seguindo o resumo,CLOCK_MONOTONIC
não. Experimente em uma VM.fonte
CLOCK_PROCESS_CPUTIME_ID
. Teste rápido:$ perl -w -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)'
-> 706724.117565279. Esse número corresponde ao tempo de atividade do sistema no Linux, mas o padrão diz que é arbitrário.CLOCK_MONOTONIC
interrompa uma suspensão / retomada seja compatível com POSIX. Supõe-se que é o tempo desde um ponto fixo no passado, mas parar o relógio ao suspender / retomar interrompe isso.POSIX 7 quotes
O POSIX 7 especifica ambos em http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html :
CLOCK_REALTIME
:CLOCK_MONOTONIC
(recurso opcional):clock_settime()
dá uma dica importante: os sistemas POSIX podem mudar arbitrariamenteCLOCK_REALITME
com ele, portanto, não confie nele fluindo nem continuamente nem para frente. O NTP pode ser implementado usandoclock_settime()
e só pode afetarCLOCK_REALITME
.A implementação do kernel Linux parece levar o tempo de inicialização como a época para
CLOCK_MONOTONIC
: Ponto de partida para CLOCK_MONOTONICfonte
Desculpe, não há reputação de adicionar isso como um comentário. Por isso, é uma resposta complementar.
Dependendo da frequência com que você liga
clock_gettime()
, lembre-se de que apenas alguns dos "relógios" são fornecidos pelo Linux no VDSO (ou seja, não exigem um syscall com toda a sobrecarga de um - o que só piorou quando o Linux foi adicionado as defesas para proteger contra ataques do tipo Espectro).Enquanto
clock_gettime(CLOCK_MONOTONIC,...)
,clock_gettime(CLOCK_REALTIME,...)
egettimeofday()
são sempre vai ser extremamente rápida (acelerada pela VDSO), este é não verdadeiro para, por exemplo CLOCK_MONOTONIC_RAW ou qualquer um dos outros relógios POSIX.Isso pode mudar com a versão do kernel e a arquitetura.
Embora a maioria dos programas não precise prestar atenção nisso, pode haver picos de latência nos relógios acelerados pelo VDSO: se você pressioná-los exatamente quando o kernel está atualizando a área de memória compartilhada com os contadores de clock, ele deve esperar pelo kernel para terminar.
Aqui está a "prova" (GitHub, para manter os bots longe do kernel.org): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7
fonte
CLOCK_REALTIME
: Tempo absoluto (por exemplo, 07/01/2020)CLOCK_MONOTONIC
: Tempo relativo (por exemplo, daqui a 5 segundos ou 10 minutos atrás)fonte