Mogę mu podać liczby zmiennoprzecinkowe, takie jak
time.sleep(0.5)
ale jak dokładne jest to? Jeśli to dam
time.sleep(0.05)
czy to naprawdę będzie spać około 50 ms?
Dokładność funkcji time.sleep zależy od dokładności uśpienia systemu operacyjnego. W przypadku systemów operacyjnych nie działających w czasie rzeczywistym, takich jak standardowy system Windows, najmniejszy odstęp czasu, w którym można spać, wynosi około 10-13 ms. Widziałem dokładne uśpienia w ciągu kilku milisekund od tego czasu, gdy powyżej minimum 10-13 ms.
Aktualizacja: Jak wspomniano w przytoczonych poniżej dokumentach, często spać w pętli, która zapewni powrót do snu, jeśli obudzi Cię wcześnie.
Powinienem również wspomnieć, że jeśli używasz Ubuntu, możesz wypróbować jądro pseudo czasu rzeczywistego (z zestawem poprawek RT_PREEMPT), instalując pakiet jądra rt (przynajmniej w Ubuntu 10.04 LTS).
EDYCJA: Korekcja jądra Linuksa nie działającego w czasie rzeczywistym ma minimalny interwał uśpienia znacznie bliższy 1 ms niż 10 ms, ale zmienia się w sposób niedeterministyczny.
sleep()
z dokumentacji „czas zawieszenia może być dłuższy niż żądany przez dowolną kwotę z powodu harmonogramu inna aktywność w systemie ”.Ludzie mają rację co do różnic między systemami operacyjnymi i jądrem, ale nie widzę żadnej szczegółowości w Ubuntu, a widzę ziarnistość 1 ms w MS7. Sugerowanie innej implementacji time.sleep, a nie tylko innej częstotliwości taktowania. Bliższa inspekcja sugeruje przy okazji ziarnistość 1μs w Ubuntu, ale wynika to z funkcji time.time, której używam do pomiaru dokładności.
źródło
Z dokumentacji :
A dokładniej wrt
sleep()
:źródło
Oto moja kontynuacja odpowiedzi Wilberta: to samo dla Mac OS X Yosemite, ponieważ nie zostało jeszcze dużo wspominane.
Wygląda na to, że przez większość czasu przesypia około 1,25 razy dłużej niż prosisz, a czasami przesypia od 1 do 1,25 razy dłużej niż prosisz. Prawie nigdy (~ dwa razy na 1000 próbek) śpi znacznie dłużej niż 1,25 razy dłużej niż żądasz.
Również (nie pokazane bezpośrednio) zależność 1,25 wydaje się utrzymywać całkiem dobrze, dopóki nie spadnie poniżej około 0,2 ms, po czym zaczyna się trochę rozmywać. Ponadto wydaje się, że rzeczywisty czas ustala się o około 5 ms dłużej niż żądasz, gdy żądany czas przekroczy 20 ms.
Ponownie wydaje się, że jest to zupełnie inna implementacja
sleep()
w systemie OS X niż w systemie Windows lub jakimkolwiek jądrze Linuksa, którego używał Wilbert.źródło
Dlaczego się nie dowiesz:
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
Dla przypomnienia, pojawia się błąd około 0,1 ms na moim HTPC i 2 ms na moim laptopie, na obu komputerach z systemem Linux.
źródło
Mała korekta, kilka osób wspomina, że sen można zakończyć wcześnie sygnałem. W dokumentach 3.6 mówi:
źródło
Naprawdę nie możesz zagwarantować niczego związanego ze snem (), z wyjątkiem tego, że przynajmniej postara się zasnąć tak długo, jak to powiedziałeś (sygnały mogą zabić twój sen, zanim upłynie czas, a wiele innych rzeczy może sprawić, że będzie działał długie).
Na pewno minimum, które możesz uzyskać w standardowym systemie operacyjnym dla komputerów stacjonarnych, będzie wynosić około 16 ms (szczegółowość timera plus czas do przełączenia kontekstu), ale są szanse, że odchylenie% od podanego argumentu będzie znaczące, gdy próbujesz spać przez 10 milisekund.
Sygnały, inne wątki przechowujące GIL, zabawa z planowaniem jądra, stopniowanie szybkości procesora itp. Mogą siać spustoszenie w czasie, w którym wątek / proces faktycznie śpi.
źródło
jeśli potrzebujesz większej precyzji lub krótszych czasów snu, rozważ stworzenie własnego:
import time def sleep(duration, get_now=time.perf_counter): now = get_now() end = now + duration while now < end: now = get_now()
źródło
Testowałem to niedawno w Pythonie 3.7 w systemie Windows 10. Precyzja wynosiła około 1 ms.
źródło
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()
Nie używaj zmiennej do przekazywania argumentu sleep (), musisz wstawić obliczenie bezpośrednio do funkcji sleep ()
I zwrot mojego terminala
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 ────────────────────
źródło
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)
W
1000
systemie Windows 7 / Python 3.8 zwrócił mi się, nawet jeśli ustawię wartość uśpienia na0.0005
więc idealny 1 ms
źródło