CLOCK_REALTIME और CLOCK_MONOTONIC में अंतर?


206

क्या आप लिनक्स पर लौटी हुई घड़ियों CLOCK_REALTIMEऔर उनके बीच अंतर बता सकते हैं ?CLOCK_MONOTONICclock_gettime()

अगर मुझे बाहरी स्रोत और वर्तमान समय द्वारा उत्पादित टाइमस्टैम्प के बीच बीते हुए समय की गणना करने की आवश्यकता है, तो कौन सा बेहतर विकल्प है?

अंत में, अगर मेरे पास एक एनटीपीसी डेमॉन है जो समय-समय पर सिस्टम के समय को समायोजित करता है, तो ये समायोजन कैसे CLOCK_REALTIMEऔर प्रत्येक के साथ बातचीत करते हैं CLOCK_MONOTONIC?

जवाबों:


238

CLOCK_REALTIMEवर्तमान दीवार-घड़ी, दिन के समय के रूप में मशीन के सर्वोत्तम-अनुमान का प्रतिनिधित्व करता है। जैसा कि इग्नासियो और मार्कआर कहते हैं, इसका मतलब यह है कि CLOCK_REALTIMEएनटीपी सहित सिस्टम दिन-प्रतिदिन की घड़ी को बदलकर आगे और पीछे कूद सकता है।

CLOCK_MONOTONICअतीत में कुछ मनमाना, निश्चित बिंदु के बाद से पूर्ण बीत चुके दीवार-घड़ी के समय का प्रतिनिधित्व करता है। यह दिन के समय प्रणाली के परिवर्तनों से प्रभावित नहीं होता है।

यदि आप एक मशीन पर एक हस्तक्षेप किए गए रिबूट के बिना देखी गई दो घटनाओं के बीच बीता हुआ समय गणना करना चाहते हैं, CLOCK_MONOTONICतो सबसे अच्छा विकल्प है।

ध्यान दें कि लिनक्स पर, CLOCK_MONOTONICसस्पेंड में बिताए समय को मापता नहीं है, हालांकि पोसिक्स परिभाषा द्वारा इसे करना चाहिए। आप CLOCK_BOOTTIMEएक मोनोटोनिक घड़ी के लिए लिनक्स-विशिष्ट का उपयोग कर सकते हैं जो सस्पेंड के दौरान चलता रहता है।


11
ध्यान दें कि नए कर्नेल पर, CLOCK_MONOTONIC_RAW उपलब्ध है जो और भी बेहतर है (कोई NTP समायोजन नहीं)।
जोसेफ गार्विन

14
@JosephGarvin "बेहतर" के कुछ मूल्य के लिए, शायद - CLOCK_MONOTONIC_RAW प्रति मिलियन (या कई सौ) भागों द्वारा वास्तविक समय में तेजी से या धीमी गति से चल सकता है, और इसकी दर पर्यावरणीय परिस्थितियों जैसे वोल्टेज या वोल्टेज (या चोरी समय) के कारण भिन्न हो सकती है आभाषी दुनिया)। ठीक से काम करने वाली मशीन पर, NTP उन सभी कारकों को कम करने के लिए अपनी पूरी कोशिश करता है और इसलिए CLOCK_MONOTONIC अधिक बारीकी से सही समय व्यतीत करता है।
हॉब्स

23
दी, यह एक CLOCK_MONOTONIC_PARBOILED है जो आवृत्ति त्रुटियों को ठीक करने के लिए NTP के प्रयासों से प्रभावित था, लेकिन चरण त्रुटियों को सही करने के अपने प्रयासों से अप्रभावित होना दिलचस्प हो सकता है, लेकिन यह एक संदिग्ध लाभ के लिए बहुत जटिलता है :)
hobbs

1
मुझे वह बात पसंद है जो @hobbs लाती है। यदि आप उन कार्यक्रमों के बारे में चिंतित हैं जो घड़ी के बहाव से प्रभावित हो सकते हैं? CLOCK_MONOTONICउस परिदृश्य में सबसे अच्छा विकल्प होगा ? जैसे पैट्रियट मिसाइल सिस्टम
sjagr

3
मुझे लगता है कि यह बताना भी महत्वपूर्ण है कि CLOCK_REALTIME लीप सेकंड से प्रभावित होता है। इसका मतलब है कि यह एक लीप सेकेंड डालने पर हर बार डबल टाइमस्टैम्प का उत्पादन करेगा । पिछली बार यह 30 जून, 2012 को हुआ था और काफी साफ्टवेयर संकट में चले गए थे
user1202136

38

रॉबर्ट लव की पुस्तक LINUX सिस्टम प्रोग्रामिंग 2 संस्करण , विशेष रूप से अध्याय 11 की शुरुआत में आपके प्रश्न को संबोधित करता है, पृष्ठ 363:

एक मोनोटोनिक समय स्रोत का महत्वपूर्ण पहलू वर्तमान मूल्य नहीं है, लेकिन गारंटी है कि समय स्रोत सख्ती से रैखिक रूप से बढ़ रहा है, और इस प्रकार दो नमूनों के बीच समय के अंतर की गणना के लिए उपयोगी है।

उस ने कहा, मेरा मानना ​​है कि वह प्रक्रियाओं को ओएस के एक ही उदाहरण पर चल रहा है, इसलिए आप चाहते हैं कि समय-समय पर अंशांकन हो सकता है जो बहाव का अनुमान लगाने में सक्षम हो।


25

CLOCK_REALTIMEएनटीपी से प्रभावित है, और आगे और पीछे की ओर बढ़ सकता है। CLOCK_MONOTONICनहीं है, और एक टिकटिक प्रति टिक पर अग्रिम।


15
CLOCK_MONOTONIC NTP के टाइम एडजस्टमेंट (टाइम स्लीपिंग) से प्रभावित होता है। हालांकि, यह कूद नहीं होगा।
derobert

3
लेकिन नए कर्नेल पर CLOCK_MONOTONIC_RAW है, जो वास्तव में NTP से प्रभावित नहीं है।
जोसेफ गार्विन

1
"टिक" - कोई भी मोटा विचार लिनक्स / amd64 पर एक बड़ा / लंबा / सीपीयू निर्देश कैसे है? या मैं इनमें से किसी पर भी डॉक्स कहां प्राप्त कर सकता हूं?
केविनरपे

@kevinarpe निश्चित रूप से नहीं है, लेकिन मुझे लगता है कि एक टिक समय के एक अंश के रूप में परिभाषित किया गया है, सीपीयू चक्र की संख्या नहीं, अक्सर यह 1/100 सेकंड है।
स्टीफन

@ स्टीफन: मुझे निश्चित रूप से 10ms से तंग होना चाहिए। मुझे लगता है कि जावा के System.nanoTime()उपयोग CLOCK_MONOTONICऔर 1000 टन या उससे कम अवधि को माप सकते हैं । शायद आप सिस्टम के समय के बारे में सोच रहे हैं, जो कभी-कभी मिलीसेकंड तक सीमित होता है?
केविनरपे

20

इग्नासियो के जवाब के अलावा , CLOCK_REALTIMEछलांग में आगे बढ़ सकते हैं, और कभी-कभी पीछे की ओर। CLOCK_MONOTONICन तो करता है; यह बस आगे की ओर जाता रहता है (हालाँकि यह शायद रिबूट पर रहता है)।

एक मजबूत ऐप को CLOCK_REALTIMEकभी-कभार (और शायद पीछे की ओर बहुत कम कभी-कभार पीछे हटने को बर्दाश्त करने में सक्षम होने की जरूरत होती है , हालांकि यह एक एज-केस की अधिकता है)।

कल्पना कीजिए कि जब आप अपने लैपटॉप को निलंबित करते हैं तो क्या होता है - CLOCK_REALTIMEफिर से शुरू होने के बाद कूदता है, CLOCK_MONOTONICनहीं। VM पर इसे आज़माएं।


3
कार्यक्रम शुरू होने पर CLOCK_MONOTONIC 0 से शुरू होता है; यह इंटरप्रोसेस के उपयोग के लिए नहीं है।
बेनुबर्ड

18
@Benubird: यह 0 से शुरू नहीं होता है जब प्रोग्राम शुरू होता है। वह है CLOCK_PROCESS_CPUTIME_ID। त्वरित परीक्षा: $ perl -w -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)'-> 706724.117565279 यह संख्या लिनक्स पर सिस्टम अपटाइम से मेल खाती है, लेकिन मानक अपनी मनमानी कहता है।
derobert

4
एक तरफ के रूप में, मुझे विश्वास नहीं है कि लिनक्स व्यवहार जहां CLOCK_MONOTONICएक सस्पेंड / फिर से शुरू होता है, पॉस-अनुरूप है। यह अतीत में एक निश्चित बिंदु के बाद का समय माना जाता है, लेकिन निलंबित / फिर से शुरू होने पर घड़ी को रोकना टूट जाता है।
कैफे

15

POSIX 7 उद्धरण

POSIX 7 दोनों http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html पर निर्दिष्ट करता है :

CLOCK_REALTIME:

यह घड़ी सिस्टम के लिए वास्तविक समय मापने वाली घड़ी का प्रतिनिधित्व करती है। इस घड़ी के लिए, मूल्य घड़ी_गेटाइम () द्वारा लौटाए गए हैं और घड़ी_सेटाइम () द्वारा निर्दिष्ट है जो युग के बाद से (सेकंड और नैनोसेकंड में) समय की मात्रा का प्रतिनिधित्व करते हैं।

CLOCK_MONOTONIC (वैकल्पिक सुविधा):

इस घड़ी के लिए, clock_gettime () द्वारा लौटाया गया मान अतीत में अनिर्दिष्ट बिंदु (उदाहरण के लिए, सिस्टम स्टार्ट-अप समय, या युग) के बाद से समय (सेकंड और नैनोसेकंड में) की मात्रा का प्रतिनिधित्व करता है। सिस्टम स्टार्ट-अप समय के बाद यह बिंदु नहीं बदलता है। CLOCK_MONOTONIC घड़ी का मान घड़ी_सेटटाइम () के माध्यम से सेट नहीं किया जा सकता है।

clock_settime()एक महत्वपूर्ण संकेत देता है: POSIX सिस्टम इसके CLOCK_REALITMEसाथ मनमाने ढंग से परिवर्तन करने में सक्षम है , इसलिए इस पर न तो निरंतर और न ही आगे बढ़ने पर भरोसा करें। NTP का उपयोग करके लागू किया जा सकता है clock_settime(), और केवल प्रभावित कर सकता है CLOCK_REALITME

Linux कर्नेल कार्यान्वयन बूट समय को निम्न के रूप में लेता हैCLOCK_MONOTONIC : CLOCK_MONOTONIC के लिए प्रारंभिक बिंदु


0

क्षमा करें, टिप्पणी के रूप में इसे जोड़ने के लिए कोई प्रतिष्ठा नहीं है। तो यह एक पूरक उत्तर के रूप में जाता है।

आप कितनी बार कॉल करेंगे clock_gettime(), इसके आधार पर , आपको यह ध्यान रखना चाहिए कि VDSO में केवल कुछ "घड़ियाँ" लिनक्स द्वारा प्रदान की जाती हैं (अर्थात एक के सभी ओवरहेड के साथ एक syscall की आवश्यकता नहीं है - जो केवल तब ही खराब हो जाती है जब लिनक्स जोड़ा जाता है स्पेक्टर जैसे हमलों से बचाने के लिए बचाव)।

हालांकि clock_gettime(CLOCK_MONOTONIC,...), clock_gettime(CLOCK_REALTIME,...)और gettimeofday()हमेशा (VDSO द्वारा त्वरित) बहुत तेज होने जा रहे हैं, यह CLOCK_MONOTONIC_RAW या किसी अन्य POSIX घड़ियों के लिए सही नहीं है।

यह कर्नेल संस्करण और आर्किटेक्चर के साथ बदल सकता है।

यद्यपि अधिकांश कार्यक्रमों को इस पर ध्यान देने की आवश्यकता नहीं है, VDSO द्वारा त्वरित घड़ियों में विलंबता स्पाइक्स हो सकते हैं: यदि आप उन्हें सही हिट करते हैं जब कर्नेल घड़ी काउंटरों के साथ साझा मेमोरी क्षेत्र को अपडेट कर रहा है, तो इसके लिए इंतजार करना होगा खत्म करने के लिए कर्नेल।

यहां "प्रमाण" (GitHub, बॉट्स को kern.org से दूर रखने के लिए): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668baf67e8748300b7

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.