C कोड में timespec_get () के सेकंड घटक से कभी-कभी समय () कभी-कभी 1 सेकंड पीछे क्यों बताया जाता है?


12

कोड का निम्नलिखित स्निपेट:

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);
    }
}

इस उत्पादन का उत्पादन:

...
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
...

क्यों के बीच विसंगति cTimeऔर ts.tv_sec? ध्यान दें कि अगर सशर्त को बदल दिया जाता है तो समस्या नहीं होती है ts.tv_nsec >= 3000000। समस्या 3000000 से छोटे होने के कारण नैनोसेकंड पर निर्भर करती है।


आपको उपयोग किए जाने वाले ऑपरेटिंग सिस्टम, इसके संस्करण, प्रयुक्त सी लाइब्रेरी के संस्करण के बारे में अधिक विशिष्ट होना चाहिए।
कुछ प्रोग्रामर

2
@Someprogrammerdude लिनक्स डेबियन 8, जीसीसी 6.3.0।
थियो डी ओर

क्या है timespec_get()? यह C या C ++ है? लगता है std::timespec_get। कृपया उपयुक्त टैग का उपयोग करें।
मार्को बोनेली

@MarcoBonelli: इसे C11 में C में जोड़ा गया था। ऑनलाइन पुन: पेश कर सकते हैं
शैडो रेंजर

@ ShadowRanger संदर्भ के लिए धन्यवाद, मैं अपने सिस्टम पर manप्रविष्टि नहीं देख सका, timespec_getइसलिए मैं निष्कर्ष पर पहुंच गया। समझ में आता है।
मार्को बोनेली

जवाबों:


11

इसका कारण यह है, कि आप (स्पष्ट रूप से) विभिन्न सिस्टम घड़ियों का उपयोग करते हैं। timespec_get()का उपयोग करता है उच्च संकल्प पूरे सिस्टम पर वास्तविक समय घड़ी, जबकि time()का उपयोग करता है मोटे वास्तविक समय घड़ी।

उपयोग करने का प्रयास करें

clock_gettime(CLOCK_REALTIME_COARSE, &ts);

आपके बजाय timespec_get(), फिर अंतर गायब हो जाना चाहिए।

संपादित करें:

यह लिनक्स कर्नेल स्रोत, vclock_gettime.c में देखा जा सकता है

दरअसल यह मुद्दा यहां देखने के लिए थोड़ा सूक्ष्म है। संरचना के सदस्यों के सेकंड-भाग द्वारा इस्तेमाल किया CLOCK_REALTIME_COARSEऔर CLOCK_REALTIMEसमान मान हैं, लेकिन नैनोसेकंड-भाग अलग है; इसके साथ CLOCK_REALTIMEइससे बड़ा 1000000000(जो एक सेकंड है) हो सकता है। इस मामले में, यह कॉल पर तय किया गया है:

ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;

यह सुधार न तो के साथ किया जाता है CLOCK_REALTIME_COARSE, न ही इसके साथ time()। यह CLOCK_REALTIMEऔर के बीच का अंतर बताता है time()


क्या यह कहीं भी प्रलेखित किया गया है, या सिर्फ एक कलाकारी के timeसाथ (संभवतः) अधिक प्रदर्शन करने वाली लेकिन कम सटीक घड़ी के साथ लागू किया जा रहा है (इस सिद्धांत पर कि इसे केवल दूसरी बारीकता ही मिली है, इसलिए किसे सटीकता की आवश्यकता है)? एक मिलीसेकंड या तो (ऑनलाइन परीक्षण एक एमएस से अधिक के सामयिक अंतराल से पता चलता है, लेकिन बहुत अधिक नहीं) जब आप केवल दूसरे ग्रैन्युलैरिटी के लिए पूछ रहे हैं, तो मुझे लगता है कि यह सब महत्वपूर्ण नहीं है।
शैडो रेंजर

@ShadowRanger मैंने कुछ और विवरण जोड़े
Ctx

इरादे का स्पष्ट दस्तावेज नहीं है, लेकिन यह एक वोट के लिए पर्याप्त विवरण है। :-) मजेदार है कि घड़ी वास्तव में एक सेकंड से अधिक अतिरिक्त नैनोसेकंड के लायक रिपोर्ट कर सकती है।
शैडो रेंजर

@ShadowRanger मुझे उसके लिए स्रोत के अलावा एक वास्तविक दस्तावेज नहीं मिला, जिसका अर्थ यह भी है, कि व्यवहार पूर्व सूचना के बिना भी विस्तार से हो सकता है
Ctx

@Ctx विस्तृत जवाब के लिए धन्यवाद! मैं घड़ी_गेट () के बजाय timespec_get () का उपयोग करूँगा जो आप सलाह देते हैं, जैसे कि timepec_get () POSIX के बजाय C11 है और उपयोग करने के लिए किस घड़ी की सेटिंग की आवश्यकता नहीं है। मुझे नहीं पता था कि अलग-अलग घड़ियों का उपयोग किया गया था, लेकिन विकल्प को देखते हुए, मुझे मोटे घड़ी का उपयोग करने में अधिक बिंदु दिखाई नहीं देते हैं।
थियो डी ओर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.