CLOCK_REALTIME ile CLOCK_MONOTONIC arasındaki fark nedir?


207

Linux'ta döndürülen saatler CLOCK_REALTIMEile CLOCK_MONOTONICsaatler arasındaki farkı açıklayabilir misiniz clock_gettime()?

Harici bir kaynak tarafından üretilen zaman damgaları ile geçen zaman arasında geçen süreyi hesaplamam gerekirse hangisi daha iyi bir seçimdir?

Son olarak, sistem saatini periyodik olarak ayarlayan bir NTP arka plan programım varsa, bu ayarlamalar CLOCK_REALTIMEve ile nasıl etkileşime girer CLOCK_MONOTONIC?

Yanıtlar:


239

CLOCK_REALTIMEmakinenin geçerli duvar saati, günün saati ile ilgili en iyi tahminini gösterir. As Ignacio ve MarkR demek, bu araçlar CLOCK_REALTIMEsistem zamanı günün-saati olarak ileri ve geri atlayabilir NTP tarafından da dahil olmak üzere değiştirilir.

CLOCK_MONOTONICgeçmişte keyfi, sabit bir noktadan bu yana geçen kesin duvar saati süresini temsil eder. Sistem günün saatindeki değişikliklerden etkilenmez.

Araya giren bir yeniden başlatma olmadan bir makinede gözlemlenen iki olay arasındaki geçen süreyi hesaplamak istiyorsanız CLOCK_MONOTONIC, en iyi seçenektir.

Linux'ta CLOCK_MONOTONICPOSIX tanımına göre askıya almada harcanan zamanı ölçmediğini unutmayın. CLOCK_BOOTTIMEAskıya alma sırasında çalışmaya devam eden monoton bir saat için Linux'a özgü kullanabilirsiniz .


11
Daha yeni çekirdeklerde CLOCK_MONOTONIC_RAW'ın daha da iyi olduğunu unutmayın (NTP ayarlaması yapılmaz).
Joseph Garvin

14
@JosephGarvin "daha iyi" bir değer için belki de - CLOCK_MONOTONIC_RAW milyonda birkaç (veya birkaç yüz) parça tarafından gerçek zamanlı hızlı veya yavaş çalışabilir ve hızı sıcaklık veya voltaj (veya çalma süresi) gibi çevresel koşullardan dolayı değişebilir Sanal makineler). Düzgün çalışan makinede, NTP tüm bu faktörlerin ve CLOCK_MONOTONIC daha yakından yansıtır böylece azaltmak için elinden geleni yapar doğrudur geçen zamanı.
Ocaklar

23
Kabul edildi, NTP'nin frekans hatalarını düzeltme çabalarından etkilenen ancak faz hatalarını düzeltme çabalarından etkilenmeyen bir CLOCK_MONOTONIC_PARBOILED olması ilginç olabilir, ancak bu şüpheli bir kazanç için çok karmaşıklıktır :)
hobbs

1
@Hobbs'un gündeme getirdiği noktayı seviyorum. Saat kaymasından etkilenebilecek programlardan endişe ediyorsanız ne olur? Misiniz CLOCK_MONOTONICbu senaryoda en iyi seçim? Örneğin Vatansever Füze Sistemi
sjagr

3
CLOCK_REALTIME'in artık saniyelerden etkilendiğini belirtmek de önemli. O Bu araçlar olacak çift üretmek bir atılım ikinci takıldığında her zaman zaman damgalarını. Son kez bu 30 Haziran 2012'de oldu ve oldukça fazla yazılım sorun yaşadı .
user1202136

38

Robert Love'ın LINUX Sistem Programlama 2. Baskı kitabı , özellikle Bölüm 11, s. 363'ün başındaki sorunuzu ele alıyor:

Monotonik bir zaman kaynağının önemli yönü mevcut değer DEĞİLDİR, ancak zaman kaynağının kesinlikle doğrusal olarak arttığının garantisi ve bu nedenle iki örnekleme arasındaki zaman farkının hesaplanmasında faydalıdır.

Bununla birlikte, süreçlerin bir işletim sisteminin aynı örneğinde çalıştığını varsaydığına inanıyorum, bu nedenle sapmayı tahmin edebilmek için periyodik bir kalibrasyon yapmak isteyebilirsiniz.


25

CLOCK_REALTIMENTP'den etkilenir ve ileri ve geri hareket edebilir. CLOCK_MONOTONICdeğil ve her kene başına bir kene ilerler.


15
CLOCK_MONOTONIC, NTP'nin zaman ayarlamasından (zaman döndürme) etkilenir. Ancak zıplamayacak.
derobert

3
Ancak daha yeni çekirdeklerde, NTP'den gerçekten etkilenmeyen CLOCK_MONOTONIC_RAW var.
Joseph Garvin

1
"tick" - Linux / amd64 üzerinde bir kene ne kadar büyük / uzun / CPU talimatları kaba bir fikir? Veya bunlardan herhangi birini nereden alabilirim?
kevinarpe

@kevinarpe Emin değilim ama bir kene zamanın bir bölümü olarak tanımlanmış, bir dizi CPU döngüsü değil, genellikle 1/100 saniye olarak tanımlanmış.
Stéphane

@ Stéphane: Kesinlikle 10 ms'den daha sıkı olmalıyım. Java'nın 1000ns veya daha az süreleriSystem.nanoTime() kullandığını CLOCK_MONOTONICve ölçebileceğini düşünüyorum . Belki bazen milisaniye ile sınırlı olan sistem zamanını düşünüyorsunuz?
kevinarpe

20

Ek olarak Ignacio'nun cevap , CLOCK_REALTIMEbazen geriye sıçramalar ileri gidip, ve olabilir. CLOCK_MONOTONIChiçbirini yapmaz; sadece ilerlemeye devam ediyor (muhtemelen yeniden başlatma sırasında sıfırlanıyor).

Sağlam bir uygulamanın CLOCK_REALTIMEzaman zaman ileriye sıçramasını tolere edebilmesi gerekir (ve bu daha çok bir uç durum olsa da, belki de çok az çok zaman zaman geriye doğru).

Dizüstü bilgisayarınızı askıya aldığınızda ne olacağını hayal edin - CLOCK_REALTIMEözgeçmişten sonra ileri atlar CLOCK_MONOTONIC, değil. Bir VM'de deneyin.


3
Program başladığında CLOCK_MONOTONIC 0'dan başlar; süreçler arası kullanım için değildir.
Benubird

18
@Benubird: Program başladığında 0'da başlamaz. İşte CLOCK_PROCESS_CPUTIME_ID. Hızlı test: $ perl -w -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)'-> 706724.117565279. Bu sayı Linux'ta sistem çalışma süresi ile eşleşiyor, ancak standart keyfi olduğunu söylüyor.
derobert

4
Bir yana, CLOCK_MONOTONICbir askıya alma / devam ettirme üzerinde durur Linux davranış POSIX uyumlu olduğuna inanmıyorum . Geçmişte sabit bir noktadan bu yana geçen zaman olması gerekiyordu, ancak saati askıya alma / devam ettirme üzerinde durdurmak bunu kırıyor.
caf

15

POSIX 7 alıntıları

POSIX 7 her ikisini de http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html adresinde belirtir :

CLOCK_REALTIME:

Bu saat, sistem için gerçek zamanı ölçen saati temsil eder. Bu saat için clock_gettime () ile döndürülen ve clock_settime () ile belirtilen değerler, Çağdan bu yana geçen süreyi (saniye ve nanosaniye cinsinden) temsil eder.

CLOCK_MONOTONIC (isteğe bağlı özellik):

Bu saat için clock_gettime () tarafından döndürülen değer, geçmişte belirtilmemiş bir noktadan (örneğin, sistem başlangıç ​​zamanı veya Dönem) beri geçen süreyi (saniye ve nanosaniye cinsinden) temsil eder. Sistem başlatma süresinden sonra bu nokta değişmez. CLOCK_MONOTONIC saatin değeri clock_settime () ile ayarlanamaz.

clock_settime()önemli bir ipucu verir: POSIX sistemleri CLOCK_REALITMEonunla keyfi olarak değişebilir , bu nedenle ne sürekli ne de ileri doğru akmasına güvenmeyin. NTP kullanılarak uygulanabilir clock_settime()ve yalnızca etkilenebilir CLOCK_REALITME.

Linux çekirdeği uygulaması, önyükleme süresini aşağıdaki gibi sürüyor gibi görünüyor CLOCK_MONOTONIC: CLOCK_MONOTONIC için başlangıç ​​noktası


0

Üzgünüz, bunu yorum olarak eklemek için itibar yok. Yani tamamlayıcı bir cevap olarak gider.

Eğer arayacak ne sıklıkta bağlı olarak clock_gettime(), sadece akılda tutmalı bazı Linux eklendiğinde sadece kötüleşti - VDSO Linux tarafından sağlanmaktadır "saatlerin" (yani tüm birinin yükü bir sistem çağrısı gerektirmeyen Spectre benzeri saldırılara karşı korunmak için savunmalar).

İken clock_gettime(CLOCK_MONOTONIC,...), clock_gettime(CLOCK_REALTIME,...)ve gettimeofday()her zaman (VDSO tarafından hızlandırılmış) son derece hızlı olacak, bu değil , mesela CLOCK_MONOTONIC_RAW veya diğer POSIX saatlerin herhangi biri için geçerlidir.

Bu, çekirdek sürümü ve mimari ile değişebilir.

Çoğu programın buna dikkat etmesi gerekmese de, VDSO tarafından hızlandırılan saatlerde gecikme ani artışları olabilir: çekirdek paylaşılan bellek alanını saat sayaçlarıyla güncellerken onlara doğru vurursanız, bitirmek için çekirdek.

İşte "kanıt" (GitHub, botları kernel.org'dan uzak tutmak için): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7


0

CLOCK_REALTIME : Mutlak süre (örneğin 07/01/2020)

CLOCK_MONOTONIC: Göreceli süre (örneğin şu andan itibaren 5 saniye veya 10 dakika önce)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.