Bisakah Anda menjelaskan perbedaan antara CLOCK_REALTIME
dan CLOCK_MONOTONIC
jam dikembalikan oleh clock_gettime()
di Linux?
Manakah pilihan yang lebih baik jika saya perlu menghitung waktu yang telah berlalu antara stempel waktu yang dihasilkan oleh sumber eksternal dan waktu saat ini?
Terakhir, jika saya memiliki daemon NTP yang secara berkala menyesuaikan waktu sistem, bagaimana penyesuaian ini berinteraksi dengan masing-masing CLOCK_REALTIME
dan CLOCK_MONOTONIC
?
CLOCK_MONOTONIC
akan menjadi pilihan terbaik dalam skenario itu? mis. Patriot Missile SystemBuku Robert Love, LINUX System Programming 2nd Edition , secara khusus membahas pertanyaan Anda di awal Bab 11, hal 363:
Yang mengatakan, saya percaya dia mengasumsikan proses berjalan pada instance yang sama dari OS, jadi Anda mungkin ingin memiliki kalibrasi berkala berjalan untuk dapat memperkirakan pergeseran.
sumber
CLOCK_REALTIME
dipengaruhi oleh NTP, dan dapat bergerak maju dan mundur.CLOCK_MONOTONIC
tidak, dan naik satu tick per tick.sumber
System.nanoTime()
menggunakanCLOCK_MONOTONIC
dan dapat mengukur durasi dari 1000ns atau kurang. Mungkin Anda berpikir tentang waktu sistem, yang terkadang terbatas pada milidetik?Selain jawaban Ignacio ,
CLOCK_REALTIME
bisa maju dengan lompatan, dan kadang-kadang mundur.CLOCK_MONOTONIC
tidak melakukan; hanya terus maju (meskipun mungkin diatur ulang saat reboot).Aplikasi yang kuat harus mampu mentolerir
CLOCK_REALTIME
lompatan ke depan sesekali (dan mungkin mundur sangat sedikit sesekali, meskipun itu lebih merupakan kasus tepi).Bayangkan apa yang terjadi ketika Anda menangguhkan laptop Anda -
CLOCK_REALTIME
melompat maju setelah resume,CLOCK_MONOTONIC
tidak. Cobalah di VM.sumber
CLOCK_PROCESS_CPUTIME_ID
. Tes cepat:$ perl -w -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)'
-> 706724.117565279. Angka itu cocok dengan waktu operasi sistem di Linux, tetapi standar mengatakan itu sewenang-wenang.CLOCK_MONOTONIC
berhenti karena penundaan / melanjutkan adalah POSIX-sesuai. Ini seharusnya menjadi waktu sejak titik tetap di masa lalu, tetapi menghentikan jam dari penundaan / melanjutkan istirahat itu.POSIX 7 kutipan
POSIX 7 menentukan keduanya di http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html :
CLOCK_REALTIME
:CLOCK_MONOTONIC
(fitur opsional):clock_settime()
memberikan petunjuk penting: sistem POSIX dapat berubah secara sewenang-wenangCLOCK_REALITME
dengannya, jadi jangan mengandalkan itu mengalir tidak terus-menerus atau maju. NTP dapat diimplementasikan menggunakanclock_settime()
, dan hanya dapat mempengaruhiCLOCK_REALITME
.Implementasi kernel Linux tampaknya mengambil waktu boot sebagai zaman untuk
CLOCK_MONOTONIC
: Titik awal untuk CLOCK_MONOTONICsumber
Maaf, tidak ada reputasi untuk menambahkan ini sebagai komentar. Demikian jawabannya sebagai pelengkap.
Tergantung pada seberapa sering Anda akan menelepon
clock_gettime()
, Anda harus ingat bahwa hanya beberapa "jam" yang disediakan oleh Linux di VDSO (yaitu tidak memerlukan syscall dengan semua overhead satu - yang hanya menjadi lebih buruk ketika Linux menambahkan pertahanan untuk melindungi dari serangan Spectre-like).Sementara
clock_gettime(CLOCK_MONOTONIC,...)
,,clock_gettime(CLOCK_REALTIME,...)
dangettimeofday()
akan selalu sangat cepat (dipercepat oleh VDSO), ini bukan benar untuk, misalnya CLOCK_MONOTONIC_RAW atau salah satu jam POSIX lainnya.Ini dapat berubah dengan versi kernel, dan arsitektur.
Meskipun sebagian besar program tidak perlu memperhatikan hal ini, mungkin ada lonjakan latensi pada jam yang dipercepat oleh VDSO: jika Anda menekannya tepat ketika kernel memperbarui area memori bersama dengan penghitung jam, ia harus menunggu untuk kernel untuk menyelesaikan.
Inilah "buktinya" (GitHub, untuk menjauhkan bot dari kernel.org): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7
sumber
CLOCK_REALTIME
: Waktu absolut (mis. 07/01/2020)CLOCK_MONOTONIC
: Waktu relatif (mis. 5 detik dari sekarang, atau 10 menit yang lalu)sumber