Saya bisa memberikannya angka floating point, seperti
time.sleep(0.5)
tapi seberapa akurat itu? Jika saya memberikannya
time.sleep(0.05)
apakah akan benar-benar tidur sekitar 50 ms?
Jawaban:
Keakuratan fungsi time.sleep tergantung pada akurasi tidur OS yang mendasarinya. Untuk OS non-realtime seperti Windows stok, interval terkecil yang dapat Anda gunakan untuk tidur adalah sekitar 10-13ms. Saya telah melihat tidur yang akurat dalam beberapa milidetik dari waktu itu ketika di atas minimum 10-13ms.
Pembaruan: Seperti yang disebutkan dalam dokumen yang dikutip di bawah ini, adalah umum untuk melakukan tidur dalam satu lingkaran yang akan memastikan untuk kembali tidur jika membangunkan Anda lebih awal.
Saya juga harus menyebutkan bahwa jika Anda menjalankan Ubuntu, Anda dapat mencoba kernel pseudo real-time (dengan set patch RT_PREEMPT) dengan menginstal paket kernel rt (setidaknya di Ubuntu 10.04 LTS).
EDIT: Koreksi kernel Linux non-realtime memiliki interval tidur minimum lebih dekat ke 1ms kemudian 10ms tetapi bervariasi dengan cara non-deterministik.
sleep()
dari dokumen "waktu penangguhan mungkin lebih lama daripada yang diminta oleh jumlah yang sewenang-wenang karena penjadwalan aktivitas lain dalam sistem ".
Orang-orang benar tentang perbedaan antara sistem operasi dan kernel, tetapi saya tidak melihat perincian di Ubuntu dan saya melihat perincian 1 ms di MS7. Menyarankan implementasi berbeda dari time.sleep, bukan hanya tick rate yang berbeda. Pemeriksaan lebih dekat menunjukkan granularitas 1μs di Ubuntu, tetapi itu karena fungsi time.time yang saya gunakan untuk mengukur akurasi.
Dari dokumentasi :
Di sisi lain, ketepatan
time()
dansleep()
lebih baik daripada padanan Unix: waktu dinyatakan sebagai bilangan floating point,time()
mengembalikan waktu paling akurat yang tersedia (menggunakan Unixgettimeofday
jika tersedia), dansleep()
akan menerima waktu dengan pecahan bukan nol (Unixselect
digunakan untuk menerapkan ini, jika tersedia).
Dan lebih khusus lagi wrt sleep()
:
Tangguhkan eksekusi selama beberapa detik. Argumennya mungkin berupa angka floating point untuk menunjukkan waktu tidur yang lebih tepat. Waktu penangguhan sebenarnya mungkin kurang dari yang diminta karena setiap sinyal yang tertangkap akan menghentikan
sleep()
pelaksanaan rutinitas penangkapan sinyal berikut. Selain itu, waktu penangguhan mungkin lebih lama dari yang diminta oleh jumlah yang sewenang-wenang karena penjadwalan aktivitas lain di sistem.
Berikut tindak lanjut saya untuk jawaban Wilbert: sama untuk Mac OS X Yosemite, karena belum banyak disebutkan.
Sepertinya banyak waktu tidur sekitar 1,25 kali dari waktu yang Anda minta dan terkadang tidur antara 1 dan 1,25 kali waktu yang Anda minta. Hampir tidak pernah (~ dua kali dari 1000 sampel) tidur secara signifikan lebih dari 1,25 kali waktu yang Anda minta.
Juga (tidak ditampilkan secara eksplisit) hubungan 1,25 tampaknya bertahan cukup baik sampai Anda berada di bawah sekitar 0,2 ms, setelah itu mulai menjadi sedikit kabur. Selain itu, waktu sebenarnya tampaknya menetap sekitar 5 md lebih lama dari yang Anda minta setelah jumlah waktu yang diminta di atas 20 md.
Sekali lagi, ini tampaknya merupakan implementasi yang sama sekali berbeda sleep()
di OS X daripada di Windows atau di mana pun Linux kernal yang digunakan Wilbert.
Mengapa Anda tidak mencari tahu:
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
Sebagai catatan, saya mendapatkan sekitar 0.1ms kesalahan pada HTPC saya dan 2ms di laptop saya, keduanya mesin linux.
Koreksi kecil, beberapa orang menyebutkan bahwa tidur bisa diakhiri lebih awal dengan sebuah sinyal. Dalam 3.6 dokumen dikatakan,
Diubah pada versi 3.5: Fungsi sekarang tidur setidaknya beberapa detik bahkan jika tidur itu diinterupsi oleh sinyal, kecuali jika penangan sinyal memunculkan pengecualian (lihat PEP 475 untuk alasannya).
Anda tidak dapat benar-benar menjamin apa pun tentang tidur (), kecuali bahwa setidaknya tidur akan berusaha sebaik mungkin selama Anda memberi tahu (sinyal dapat mematikan tidur Anda sebelum waktu habis, dan banyak lagi hal yang dapat membuatnya berjalan panjang).
Yang pasti, minimum yang bisa Anda peroleh pada sistem operasi desktop standar adalah sekitar 16 ms (perincian pengatur waktu ditambah waktu ke sakelar konteks), tetapi kemungkinan% deviasi dari argumen yang diberikan akan menjadi signifikan ketika Anda mencoba tidur selama 10 milidetik.
Sinyal, utas lain yang menahan GIL, kesenangan penjadwalan kernel, peningkatan kecepatan prosesor, dll. Semuanya dapat merusak dengan durasi utas / proses Anda benar-benar tidur.
Diuji baru-baru ini pada Python 3.7 di Windows 10. Presisi sekitar 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()
Jangan gunakan variabel untuk meneruskan argumen sleep (), Anda harus memasukkan kalkulasi langsung ke sleep ()
Dan kembalinya terminal saya
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)
Pada windows 7 / Python 3.8 dikembalikan 1000
untuk saya, bahkan jika saya menyetel nilai sleep ke0.0005
jadi 1ms sempurna