2009-07-15 19 views

उत्तर

55

time.sleep फ़ंक्शन की सटीकता आपके अंतर्निहित ओएस की नींद सटीकता की सटीकता पर निर्भर करती है। गैर-रीयलटाइम ओएस के लिए एक स्टॉक की तरह विंडोज़ के लिए सबसे छोटा अंतराल आप लगभग 10-13ms के लिए सो सकते हैं। मैंने उस समय के कई मिलीसेकंड के भीतर सटीक नींद देखी है जब न्यूनतम 10-13ms से ऊपर है।

अद्यतन: नीचे दिए गए दस्तावेज़ों में उल्लिखित की तरह, एक लूप में नींद करना आम है जो आपको जल्दी उठने पर सोने के लिए वापस जाने के लिए सुनिश्चित करेगा।

मुझे यह भी जिक्र करना चाहिए कि यदि आप उबंटू चला रहे हैं तो आप आरटी कर्नेल पैकेज (कम से कम उबंटू 10.04 एलटीएस) स्थापित करके एक छद्म रीयल-टाइम कर्नेल (RT_PREEMPT पैच सेट के साथ) का प्रयास कर सकते हैं।

संपादित करें: सुधार गैर-रीयलटाइम लिनक्स कर्नेल में न्यूनतम नींद अंतराल 1ms के करीब 1ms के करीब है लेकिन यह एक गैर-निर्धारक तरीके से भिन्न होता है।

+7

असल में, लिनक्स कर्नेल काफी समय तक उच्च टिक दर पर चूक गए हैं, इसलिए "न्यूनतम" नींद 10ms से 1ms के करीब है। इसकी गारंटी नहीं है - अन्य सिस्टम गतिविधि कर्नेल को आपकी प्रक्रिया को जितनी जल्दी हो सके शेड्यूल करने में असमर्थ हो सकती है, यहां तक ​​कि सीपीयू विवाद के बिना भी। रीयलटाइम कर्नेल ठीक करने की कोशिश कर रहे हैं, मुझे लगता है। लेकिन, जब तक आपको वास्तव में रीयलटाइम व्यवहार की आवश्यकता नहीं होती है, तो बस एक उच्च टिक दर (कर्नेल एचजेड सेटिंग) का उपयोग करके आपको गारंटी नहीं मिलती है, लेकिन उच्च-रिज़ॉल्यूशन कुछ भी विशेष उपयोग किए बिना लिनक्स में सो जाता है। –

+1

हाँ आप सही हैं, मैंने लिनक्स 2.6.24-24 के साथ प्रयास किया और 1000 हर्ट्ज अपडेट दरों के करीब पहुंचने में सक्षम था। उस समय मैं यह कर रहा था मै मैक और विंडोज पर भी कोड चला रहा था, इसलिए शायद मैं उलझन में आया। मुझे पता है कि विंडोज एक्सपी कम से कम 10 एमएमएस की टिक दर है। –

+0

विंडोज 8 पर मुझे केवल 2 एमएमएस – markmnl

19

documentation से: time() सबसे सटीक समय रिटर्न बार चल बिन्दु संख्या के रूप में व्यक्त कर रहे हैं,:

दूसरी ओर, time() और sleep() की शुद्धता की तुलना में बेहतर उनके यूनिक्स समकक्ष है उपलब्ध (यूनिक्स gettimeofday जहां उपलब्ध हो) का उपयोग करके, और sleep() एक गैर-शून्य अंश (यूनिक्स) के साथ एक समय स्वीकार करेगाका उपयोग को लागू करने के लिए किया जाता है, जहां उपलब्ध हो)।

और more specifically w.r.t. sleep():

दिए गए नंबर सेकंड के लिए निष्पादन को निलंबित करें। अधिक सटीक नींद का समय इंगित करने के लिए तर्क फ़्लोटिंग पॉइंट नंबर हो सकता है। वास्तविक निलंबन समय कम कि का अनुरोध किया है क्योंकि किसी भी पकड़ा संकेत कि संकेत के पकड़ने दिनचर्या के sleep() निम्नलिखित निष्पादन को समाप्त कर देगा हो सकता है। इसके अलावा, निलंबन समय अब मंडल के अन्य गतिविधि के शेड्यूलिंग के कारण एक मनमाना राशि से अनुरोध किया की तुलना में हो सकता है।

+1

क्या कोई भी बता सकता है "क्योंकि किसी भी पकड़े गए सिग्नल ने उस सिग्नल के आकर्षक दिनचर्या के निष्पादन के बाद नींद() को समाप्त कर दिया है? यह किस संकेत का जिक्र कर रहा है? धन्यवाद! –

+0

सिग्नल नोटिफिकेशन की तरह हैं जो ओएस प्रबंधित करता है (http://en.wikipedia.org/wiki/Unix_signal), इसका मतलब है कि यदि ओएस सिग्नल पकड़ा जाता है, तो उस सिग्नल के इलाज के बाद नींद() समाप्त हो जाती है। – ArianJM

2

आप वास्तव में नींद() के बारे में कुछ भी गारंटी नहीं दे सकते हैं, सिवाय इसके कि जब तक आप इसे बताएंगे, तब तक सोने के लिए सबसे अच्छा प्रयास किया जाएगा (सिग्नल समय से पहले आपकी नींद को मार सकता है, और बहुत सी चीजें इसे लंबे समय तक चला सकते हैं)।निश्चित रूप से आप एक मानक डेस्कटॉप ऑपरेटिंग सिस्टम पर प्राप्त कर सकते हैं न्यूनतम 16ms (टाइमर ग्रैन्युलरिटी और संदर्भ स्विच के लिए समय) होने जा रहा है, लेकिन संभावना है कि प्रदत्त तर्क से% विचलन महत्वपूर्ण हो रहा है जब आप कोशिश कर रहे हैं मिलीसेकंड के 10 के लिए सो जाओ। सिग्नल, जीआईएल धारण करने वाले अन्य थ्रेड, कर्नेल शेड्यूलिंग मज़े, प्रोसेसर स्पीड स्टेपिंग इत्यादि सभी आपकी थ्रेड/प्रक्रिया वास्तव में सोते समय अवधि के साथ विनाश कर सकते हैं।

+2

प्रलेखन अन्यथा कहता है: > वास्तविक निलंबन समय अनुरोधित से कम हो सकता है क्योंकि किसी भी पकड़े गए सिग्नल उस सिग्नल के आकर्षक दिनचर्या के निष्पादन के बाद नींद() को समाप्त कर देगा। –

+0

आह निष्पक्ष बिंदु, पोस्ट को ठीक किया गया है, हालांकि लंबी नींद आ रही है() कम लोगों की तुलना में अधिक संभावना है। –

+1

साढ़े सालों बाद ... दस्तावेज अभी भी झूठ बोल रहा है। विंडोज़ पर, सिग्नल नींद को समाप्त नहीं करेंगे()। पायथन 3.2, विनएक्सपी एसपी 3 पर परीक्षण किया गया। – Dave

14

तुम बाहर क्यों मिल रहा है नहीं:

from datetime import datetime 
import time 

def check_sleep(amount): 
    start = datetime.now() 
    time.sleep(amount) 
    end = datetime.now() 
    delta = end-start 
    return delta.seconds + delta.microseconds/1000000. 

error = sum(abs(check_sleep(0.050)-0.050) for i in xrange(100))*10 
print "Average error is %0.2fms" % error 

रिकॉर्ड के लिए, मैं आसपास मेरे HTPC और अपने लैपटॉप, दोनों linux मशीनों पर 2ms पर त्रुटि 0.1ms।

+8

अनुभवजन्य परीक्षण आपको एक बहुत संकीर्ण दृश्य देगा। कई कर्नल, ऑपरेटिंग सिस्टम और कर्नेल कॉन्फ़िगरेशन हैं जो इसे प्रभावित करते हैं। पुराने लिनक्स कर्नेल कम टिक दर के लिए डिफ़ॉल्ट होते हैं, जिसके परिणामस्वरूप अधिक ग्रॅन्युलरिटी होती है। यूनिक्स कार्यान्वयन में, नींद के दौरान एक बाहरी संकेत इसे किसी भी समय रद्द कर देगा, और अन्य कार्यान्वयन में समान बाधाएं हो सकती हैं। –

+5

बेशक अनुभवजन्य अवलोकन स्थानांतरण योग्य नहीं है। ऑपरेटिंग सिस्टम और कर्नेल के अलावा वहां बहुत से क्षणिक मुद्दे हैं जो इसे प्रभावित करते हैं। यदि हार्ड रीयल टाइम गारंटी की आवश्यकता है तो हार्डवेयर सिस्टम से पूरे सिस्टम डिज़ाइन को ध्यान में रखा जाना चाहिए। मैंने अभी बयान के आधार पर प्रासंगिक परिणाम पाए हैं कि 10ms न्यूनतम सटीकता है। मैं विंडोज़ दुनिया में घर पर नहीं हूं, लेकिन ज्यादातर लिनक्स डिस्ट्रोज़ थोड़ी देर के लिए टिकरलेस कर्नेल चला रहे हैं। बहुआयामी के साथ अब प्रचलित है कि यह वास्तव में टाइमआउट के करीब निर्धारित होने की संभावना है। –

+3

अच्छा अनुभवजन्य कोड – cregox

41

लोग ऑपरेटिंग सिस्टम और कर्नेल के बीच अंतर के बारे में काफी सही हैं, लेकिन मुझे उबंटू में कोई ग्रैन्युलरिटी दिखाई नहीं दे रही है और मुझे एमएस 7 में 1 एमएस ग्रैन्युलरिटी दिखाई देती है। Time.sleep के एक अलग कार्यान्वयन का सुझाव, सिर्फ एक अलग टिक दर नहीं। निकट निरीक्षण निरीक्षण से उबंटू में 1μs ग्रैन्युलरिटी का सुझाव देता है, लेकिन यह उस समय के कारण होता है जब मैं सटीकता को मापने के लिए उपयोग करता हूं। Linux and Windows typical time.sleep behaviour in Python

+5

के लिए +1 यह दिलचस्प है कि कैसे लिनक्स ने अनुरोध से थोड़ा अधिक समय तक सोना चुना है, जबकि माइक्रोसॉफ्ट ने विपरीत दृष्टिकोण चुना है। – jleahy

+2

@jleahy - लिनक्स दृष्टिकोण मेरे लिए समझ में आता है: नींद वास्तव में समय की राशि जिसके बाद आप एक बार फिर से (अनुसूचक की इच्छा के अपने आप को प्रस्तुत जो या तुरंत निष्पादन के लिए आप समय निर्धारित नहीं हो सकता है के लिए निष्पादन प्राथमिकता के एक रिलीज है)। – underrun

+0

@underrun बहुत सच है। – jleahy

11

यहां विल्बर्ट के उत्तर के लिए मेरा अनुवर्ती है: मैक ओएस एक्स योसेमेट के लिए यह वही है, क्योंकि इसका अभी तक उल्लेख नहीं किया गया है। Sleep behavior of Mac OS X Yosemite

ऐसा लगता है कि आप अनुरोध करते समय लगभग 1.25 गुना सोते हैं और कभी-कभी अनुरोध करते समय 1 और 1.25 गुना के बीच सोते हैं। यह लगभग कभी नहीं (~ 1000 नमूनों में से दो बार) आपके द्वारा अनुरोध किए जाने पर 1.25 गुना अधिक महत्वपूर्ण रूप से सोता है।

इसके अलावा (स्पष्ट रूप से नहीं दिखाया गया है) 1.25 रिलेशनशिप बहुत अच्छी तरह से पकड़ता प्रतीत होता है जब तक आप लगभग 0.2 एमएस नीचे नहीं आते, जिसके बाद यह थोड़ा अस्पष्ट हो जाता है। इसके अतिरिक्त, वास्तविक समय 20 एमएस से ऊपर आने वाले समय के बाद अनुरोध के मुकाबले लगभग 5 एमएस लंबा रहता है।

फिर से, यह विंडोज़ की तुलना में ओएस एक्स में sleep() या जो भी लिनक्स कर्नल विल्बर्ट का उपयोग कर रहा था, का एक पूरी तरह से अलग कार्यान्वयन प्रतीत होता है।

+0

क्या आप बेंचमार्क के लिए github/bitbucket में स्रोत कोड अपलोड कर सकते हैं? – jfs

+0

हाँ, कोड [यहां] है (http://pastebin.com/KrhpL21R)। –

+2

मैंने अपनी मशीन पर [it] (http://pastebin.com/5cmMaJjb) की कोशिश की है। [परिणाम @ विल्बर्ट के उत्तर के समान है] (http://i.stack.imgur.com/l8L9M.png)। – jfs

संबंधित मुद्दे