Tôi có thể cung cấp cho nó số dấu phẩy động, chẳng hạn như
time.sleep(0.5)
nhưng độ chính xác của nó là bao nhiêu? Nếu tôi đưa nó
time.sleep(0.05)
nó sẽ thực sự ngủ khoảng 50 ms?
Câu trả lời:
Độ chính xác của chức năng time.sleep phụ thuộc vào độ chính xác khi ngủ của hệ điều hành cơ bản của bạn. Đối với hệ điều hành không thời gian thực như Windows cổ phiếu, khoảng thời gian nhỏ nhất bạn có thể ngủ là khoảng 10-13ms. Tôi đã thấy những giấc ngủ chính xác trong vòng vài mili giây của thời gian đó khi trên mức tối thiểu 10-13ms.
Cập nhật: Giống như được đề cập trong các tài liệu được trích dẫn bên dưới, thông thường bạn sẽ thực hiện chế độ ngủ theo vòng lặp để đảm bảo bạn sẽ quay lại ngủ nếu nó đánh thức bạn sớm.
Tôi cũng nên đề cập rằng nếu bạn đang chạy Ubuntu, bạn có thể thử một nhân thời gian thực giả (với bộ bản vá RT_PREEMPT) bằng cách cài đặt gói nhân rt (ít nhất là trong Ubuntu 10.04 LTS).
CHỈNH SỬA: Sửa chữa các hạt nhân Linux không theo thời gian thực có khoảng thời gian nghỉ tối thiểu gần 1ms rồi 10ms nhưng nó thay đổi theo cách không xác định.
sleep()
từ tài liệu "thời gian tạm ngưng có thể lâu hơn yêu cầu bởi một lượng tùy ý vì lịch trình của hoạt động khác trong hệ thống ”.
Mọi người khá đúng về sự khác biệt giữa hệ điều hành và hạt nhân, nhưng tôi không thấy bất kỳ mức độ chi tiết nào trong Ubuntu và tôi thấy mức độ chi tiết 1 ms trong MS7. Đề xuất một cách triển khai time.sleep khác, không chỉ một tỷ lệ đánh dấu khác. Kiểm tra kỹ hơn cho thấy mức độ chi tiết 1μs trong Ubuntu, nhưng đó là do chức năng time.time mà tôi sử dụng để đo độ chính xác.
Từ tài liệu :
Mặt khác, độ chính xác của
time()
vàsleep()
tốt hơn các điểm tương đương Unix của chúng: thời gian được biểu thị dưới dạng số dấu phẩy động,time()
trả về thời gian chính xác nhất hiện có (sử dụng Unixgettimeofday
nếu có) vàsleep()
sẽ chấp nhận thời gian có phân số khác 0 (Unixselect
được sử dụng để thực hiện điều này, nếu có).
Và cụ thể hơn là wrt sleep()
:
Tạm dừng thực thi trong số giây nhất định. Đối số có thể là một số dấu phẩy động để chỉ ra thời gian ngủ chính xác hơn. Thời gian tạm ngừng thực tế có thể ít hơn thời gian yêu cầu vì bất kỳ tín hiệu bắt được nào sẽ chấm dứt việc
sleep()
thực hiện quy trình bắt tín hiệu đó sau đó. Ngoài ra, thời gian tạm ngừng có thể lâu hơn yêu cầu bởi một số lượng tùy ý vì lịch trình của hoạt động khác trong hệ thống.
Đây là phần tiếp theo của tôi đối với câu trả lời của Wilbert: Mac OS X Yosemite cũng vậy, vì nó vẫn chưa được đề cập nhiều.
Có vẻ như rất nhiều thời gian nó ngủ gấp khoảng 1,25 lần thời gian bạn yêu cầu và đôi khi ngủ gấp từ 1 đến 1,25 lần thời gian bạn yêu cầu. Nó gần như không bao giờ (~ hai lần trong số 1000 mẫu) ngủ nhiều hơn đáng kể 1,25 lần thời gian bạn yêu cầu.
Ngoài ra (không được hiển thị rõ ràng) mối quan hệ 1,25 dường như giữ khá tốt cho đến khi bạn xuống dưới khoảng 0,2 ms, sau đó nó bắt đầu hơi mờ. Ngoài ra, thời gian thực tế dường như dài hơn khoảng 5 mili giây so với yêu cầu của bạn sau khi lượng thời gian yêu cầu vượt quá 20 mili giây.
Một lần nữa, nó dường như là một cách triển khai hoàn toàn khác sleep()
trong OS X so với trong Windows hoặc bất kỳ Linux nào kernal Wilbert đang sử dụng.
Tại sao bạn không tìm hiểu:
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
Đối với hồ sơ, tôi gặp lỗi khoảng 0,1ms trên HTPC và 2ms trên máy tính xách tay của tôi, cả hai máy Linux.
Một điều chỉnh nhỏ, một số người đề cập rằng giấc ngủ có thể kết thúc sớm bằng một tín hiệu. Trong 3,6 tài liệu, nó nói,
Đã thay đổi trong phiên bản 3.5: Chức năng hiện ở chế độ ngủ ít nhất vài giây ngay cả khi chế độ ngủ bị gián đoạn bởi một tín hiệu, ngoại trừ trường hợp trình xử lý tín hiệu đưa ra một ngoại lệ (xem PEP 475 để biết lý do).
Bạn thực sự không thể đảm bảo bất cứ điều gì về giấc ngủ (), ngoại trừ việc ít nhất nó sẽ cố gắng hết sức để ngủ miễn là bạn đã nói với nó (các tín hiệu có thể giết chết giấc ngủ của bạn trước khi hết giờ và nhiều thứ khác có thể khiến nó chạy Dài).
Để chắc chắn rằng mức tối thiểu bạn có thể nhận được trên một hệ điều hành máy tính để bàn tiêu chuẩn sẽ là khoảng 16ms (độ chi tiết của bộ đếm thời gian cộng với thời gian chuyển đổi ngữ cảnh), nhưng rất có thể độ lệch% so với đối số được cung cấp sẽ là đáng kể khi bạn đang thử để ngủ trong 10 giây mili giây.
Tín hiệu, các luồng khác giữ GIL, niềm vui lên lịch hạt nhân, bước tốc độ bộ xử lý, v.v. đều có thể tàn phá với thời gian luồng / quy trình của bạn thực sự ngủ.
Đã kiểm tra điều này gần đây trên Python 3.7 trên Windows 10. Độ chính xác là khoảng 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()
Không sử dụng một biến để chuyển đối số của sleep (), bạn phải chèn phép tính trực tiếp vào sleep ()
Và sự trở lại của thiết bị đầu cuối của tôi
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 ─────────────────────