ฉันสามารถให้ตัวเลขทศนิยมได้เช่น
time.sleep(0.5)
แต่มันแม่นยำแค่ไหน? ถ้าฉันให้มัน
time.sleep(0.05)
มันจะนอนประมาณ 50 ms จริงหรือ?
ฉันสามารถให้ตัวเลขทศนิยมได้เช่น
time.sleep(0.5)
แต่มันแม่นยำแค่ไหน? ถ้าฉันให้มัน
time.sleep(0.05)
มันจะนอนประมาณ 50 ms จริงหรือ?
คำตอบ:
ความแม่นยำของเวลาฟังก์ชันการนอนหลับขึ้นอยู่กับความแม่นยำในการนอนหลับของระบบปฏิบัติการของคุณ สำหรับระบบปฏิบัติการที่ไม่ใช่แบบเรียลไทม์เช่น Windows ในสต็อกช่วงเวลาที่น้อยที่สุดที่คุณสามารถนอนหลับได้คือประมาณ 10-13ms ฉันได้เห็นการนอนหลับที่แม่นยำภายในไม่กี่มิลลิวินาทีของเวลานั้นเมื่อสูงกว่าค่าต่ำสุด 10-13 มิลลิวินาที
อัปเดต: เช่นเดียวกับที่กล่าวไว้ในเอกสารที่อ้างถึงด้านล่างเป็นเรื่องปกติที่จะนอนหลับเป็นวงรอบซึ่งจะทำให้คุณกลับไปนอนหลับได้หากตื่น แต่เช้า
ฉันควรพูดถึงว่าหากคุณใช้ Ubuntu คุณสามารถลองใช้เคอร์เนลหลอกแบบเรียลไทม์ (ด้วยชุดแพทช์ RT_PREEMPT) โดยติดตั้งแพ็คเกจเคอร์เนล rt (อย่างน้อยใน Ubuntu 10.04 LTS)
แก้ไข: การแก้ไขเคอร์เนลลินุกซ์ที่ไม่ใช่เรียลไทม์มีช่วงเวลาการนอนหลับขั้นต่ำที่ใกล้ 1ms จากนั้น 10ms แต่จะแตกต่างกันไปในลักษณะที่ไม่ได้กำหนด
sleep()
จากเอกสาร "เวลาในการระงับอาจนานกว่าที่ร้องขอโดยพลการเนื่องจากการกำหนดเวลาของ กิจกรรมอื่น ๆ ในระบบ ".
ผู้คนค่อนข้างถูกต้องเกี่ยวกับความแตกต่างระหว่างระบบปฏิบัติการและเมล็ด แต่ฉันไม่เห็นรายละเอียดใด ๆ ใน Ubuntu และฉันเห็นความละเอียด 1 มิลลิวินาทีใน MS7 แนะนำการใช้งานเวลานอนที่แตกต่างกันไม่ใช่แค่อัตราเห็บที่แตกต่างกัน การตรวจสอบอย่างใกล้ชิดแสดงให้เห็นถึงความละเอียด1μsใน Ubuntu แต่นั่นเป็นเพราะฟังก์ชัน time.time ที่ฉันใช้ในการวัดความแม่นยำ
จากเอกสารประกอบ :
บนมืออื่น ๆ , ความแม่นยำของ
time()
และsleep()
จะดีกว่าเทียบเท่ายูนิกซ์ของพวกเขาครั้งจะแสดงเป็นตัวเลขทศนิยม,time()
ส่งกลับเวลาที่ถูกต้องที่สุดที่มีอยู่ (โดยใช้ระบบปฏิบัติการยูนิกซ์gettimeofday
มี) และsleep()
จะยอมรับเวลากับส่วนที่ไม่ใช่ศูนย์ A (Unixselect
ถูกนำมาใช้ เพื่อใช้สิ่งนี้หากมี)
และโดยเฉพาะมากขึ้น wrt sleep()
:
ระงับการดำเนินการตามจำนวนวินาทีที่กำหนด อาร์กิวเมนต์อาจเป็นตัวเลขทศนิยมเพื่อระบุเวลานอนหลับที่แม่นยำยิ่งขึ้น เวลาระงับจริงอาจน้อยกว่าที่ร้องขอเนื่องจากสัญญาณที่จับได้จะยุติการ
sleep()
ดำเนินการตามขั้นตอนการจับสัญญาณดังต่อไปนี้ นอกจากนี้เวลาระงับอาจนานกว่าที่ร้องขอโดยพลการเนื่องจากการจัดกำหนดการของกิจกรรมอื่น ๆ ในระบบ
นี่คือการติดตามคำตอบของ Wilbert: เช่นเดียวกับ Mac OS X Yosemite เนื่องจากยังไม่ได้รับการกล่าวถึงมากนัก
ดูเหมือนว่าส่วนมากจะนอนประมาณ 1.25 เท่าของเวลาที่คุณขอและบางครั้งก็นอนระหว่าง 1 ถึง 1.25 เท่าของเวลาที่คุณขอ แทบไม่เคยเลย (~ สองเท่าจาก 1,000 ตัวอย่าง) นอนหลับมากกว่า 1.25 เท่าของเวลาที่คุณร้องขออย่างมีนัยสำคัญ
นอกจากนี้ (ไม่ได้แสดงอย่างชัดเจน) ความสัมพันธ์ 1.25 ดูเหมือนจะค่อนข้างดีจนกว่าคุณจะได้ต่ำกว่า 0.2 ms หลังจากนั้นมันก็เริ่มเลือนลางเล็กน้อย นอกจากนี้เวลาจริงดูเหมือนว่าจะยาวกว่าที่คุณร้องขอประมาณ 5 มิลลิวินาทีหลังจากระยะเวลาที่ร้องขอสูงกว่า 20 มิลลิวินาที
อีกครั้งดูเหมือนว่าจะเป็นการใช้งานsleep()
ใน OS X ที่แตกต่างอย่างสิ้นเชิงกับใน Windows หรือที่เคอร์เนลของลินุกซ์ที่ Wilbert ใช้อยู่
ทำไมคุณไม่ค้นหา:
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
สำหรับบันทึกฉันพบข้อผิดพลาดประมาณ 0.1ms ใน HTPC และ 2ms บนแล็ปท็อปของฉันทั้งเครื่อง linux
การแก้ไขเล็กน้อยหลายคนพูดถึงว่าการนอนหลับสามารถยุติได้เร็วด้วยสัญญาณ ใน3.6 เอกสารระบุว่า
การเปลี่ยนแปลงในเวอร์ชัน 3.5: ขณะนี้ฟังก์ชันจะเข้าสู่โหมดสลีปอย่างน้อยวินาทีแม้ว่าการสลีปจะถูกขัดจังหวะด้วยสัญญาณยกเว้นว่าตัวจัดการสัญญาณจะยกข้อยกเว้น (ดูPEP 475สำหรับเหตุผล)
คุณไม่สามารถรับประกันอะไรเกี่ยวกับการนอนหลับได้จริงๆ () ยกเว้นว่าอย่างน้อยก็จะพยายามอย่างเต็มที่ที่จะนอนหลับให้นานที่สุดเท่าที่คุณบอกไว้ (สัญญาณสามารถฆ่าการนอนหลับของคุณก่อนเวลาจะหมดและสิ่งอื่น ๆ อีกมากมายที่สามารถทำให้มันทำงานได้ ยาว).
แน่นอนว่าขั้นต่ำที่คุณจะได้รับบนระบบปฏิบัติการเดสก์ท็อปมาตรฐานจะอยู่ที่ประมาณ 16ms (ความละเอียดของตัวจับเวลาบวกเวลาในการสลับบริบท) แต่โอกาสที่ค่าเบี่ยงเบน% จากอาร์กิวเมนต์ที่ให้มาจะมีความสำคัญเมื่อคุณพยายาม เข้านอนเป็นเวลา 10 วินาทีของมิลลิวินาที
สัญญาณ, เธรดอื่น ๆ ที่ถือ GIL, ความสนุกสนานในการตั้งเวลาเคอร์เนล, การเพิ่มความเร็วของโปรเซสเซอร์ ฯลฯ ทั้งหมดสามารถสร้างความเสียหายได้ด้วยระยะเวลาที่เธรด / กระบวนการของคุณเข้าสู่โหมดสลีป
หากคุณต้องการความแม่นยำมากขึ้นหรือลดเวลาในการนอนให้ลองตัดสินใจด้วยตัวคุณเอง:
import time
def sleep(duration, get_now=time.perf_counter):
now = get_now()
end = now + duration
while now < end:
now = get_now()
ทดสอบสิ่งนี้เมื่อเร็ว ๆ นี้กับ Python 3.7 บน Windows 10 ความแม่นยำอยู่ที่ประมาณ 1ms
def start(self):
sec_arg = 10.0
cptr = 0
time_start = time.time()
time_init = time.time()
while True:
cptr += 1
time_start = time.time()
time.sleep(((time_init + (sec_arg * cptr)) - time_start ))
# AND YOUR CODE .......
t00 = threading.Thread(name='thread_request', target=self.send_request, args=([]))
t00.start()
อย่าใช้ตัวแปรเพื่อส่งผ่านอาร์กิวเมนต์ของการนอนหลับ () คุณต้องแทรกการคำนวณลงในโหมดสลีปโดยตรง ()
และการกลับมาของขั้วของฉัน
1 นาที 17: 20: 16.891 ───────────────────
2 นาที 17: 20: 18.891 ───────────────────
3 นาที 17: 20: 20.891 ───────────────────
4 นาที 17: 20: 22.891 ───────────────────
5 นาที 17: 20: 24.891 ───────────────────
....
689 ─── 17: 43: 12.891 ────────────────────
690 ─── 17: 43: 14.890 ────────────────────
691 ─── 17: 43: 16.891 ────────────────────
692 ─── 17: 43: 18.890 ────────────────────
693 ─── 17: 43: 20.891 ────────────────────
...
727 ─── 17: 44: 28.891 ────────────────────
728 ─── 17: 44: 30.891 ────────────────────
729 ─── 17: 44: 32.891 ────────────────────
730 ─── 17: 44: 34.890 ────────────────────
731 ─── 17: 44: 36.891 ────────────────────
def test():
then = time.time() # get time at the moment
x = 0
while time.time() <= then+1: # stop looping after 1 second
x += 1
time.sleep(0.001) # sleep for 1 ms
print(x)
บน windows 7 / Python 3.8 ส่งคืน1000
สำหรับฉันแม้ว่าฉันจะตั้งค่าการนอนหลับเป็น0.0005
1 มิลลิวินาทีที่สมบูรณ์แบบ