Я могу дать ему числа с плавающей запятой, например
time.sleep(0.5)
но насколько это точно? Если я дам это
time.sleep(0.05)
он действительно будет спать около 50 мс?
Ответы:
Точность функции time.sleep зависит от точности сна вашей базовой ОС. Для ОС, не работающих в реальном времени, таких как стандартная Windows, наименьший интервал, в течение которого вы можете спать, составляет около 10-13 мс. Я видел точный сон в течение нескольких миллисекунд с того времени, когда он превышал минимальные 10-13 мс.
Обновление: как упоминалось в документах, цитируемых ниже, обычно засыпают в цикле, который обязательно вернется в режим сна, если он вас разбудит рано.
Я также должен упомянуть, что если вы используете Ubuntu, вы можете опробовать ядро псевдореального времени (с установленным патчем RT_PREEMPT), установив пакет ядра rt (по крайней мере, в Ubuntu 10.04 LTS).
РЕДАКТИРОВАТЬ: Ядра Linux исправления не в реальном времени имеют минимальный интервал сна, намного ближе к 1 мс, а затем к 10 мс, но он варьируется недетерминированным образом.
sleep()
из документации «время приостановки может быть больше, чем запрошено произвольной суммой, из-за планирования другая деятельность в системе ».
Люди совершенно правы в отношении различий между операционными системами и ядрами, но я не вижу гранулярности в Ubuntu, а в MS7 я вижу гранулярность 1 мс. Предлагая другую реализацию time.sleep, а не просто другую скорость тиков. Кстати, при более внимательном рассмотрении можно предположить, что в Ubuntu гранулярность составляет 1 мкс, но это связано с функцией time.time, которую я использую для измерения точности.
Из документации :
С другой стороны, точность
time()
иsleep()
лучше, чем их эквиваленты в Unix: время выражается как числа с плавающей запятой,time()
возвращает наиболее точное доступное время (с использованием Unix,gettimeofday
где это возможно) иsleep()
принимает время с ненулевой дробью (select
используется Unix. чтобы реализовать это, где это возможно).
И более конкретно WRT sleep()
:
Приостановить выполнение на указанное количество секунд. Аргументом может быть число с плавающей запятой, чтобы указать более точное время сна. Фактическое время приостановки может быть меньше запрошенного, потому что любой пойманный сигнал завершит
sleep()
последующее выполнение процедуры улавливания этого сигнала. Кроме того, время приостановки может быть больше, чем запрошено произвольной величиной, из-за планирования других действий в системе.
Вот мое продолжение ответа Уилберта: то же самое и для Mac OS X Yosemite, так как об этом пока особо не упоминалось.
Похоже, что большую часть времени он спит примерно в 1,25 раза больше времени, чем вы запрашиваете, а иногда спит от 1 до 1,25 раза больше времени, которое вы запрашиваете. Он почти никогда (~ два раза из 1000 образцов) спит значительно больше, чем в 1,25 раза больше времени, чем вы запрашиваете.
Также (не показано явно) соотношение 1,25, кажется, довольно хорошо сохраняется, пока вы не опуститесь ниже примерно 0,2 мс, после чего оно начинает становиться немного нечетким. Кроме того, фактическое время, кажется, устанавливается примерно на 5 мс дольше, чем вы запрашиваете, после того как запрошенное время превышает 20 мс.
Опять же, похоже, что это совершенно другая реализация sleep()
в OS X, чем в Windows или любом другом ядре Linux, которое использовал Уилберт.
Почему ты не узнаешь:
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,1 мс на моем HTPC и 2 мс на моем ноутбуке, обе машины с Linux.
Небольшая поправка, некоторые люди упоминают, что сон можно преждевременно прервать по сигналу. В документах 3.6 говорится:
Изменено в версии 3.5: функция теперь спит не менее секунд, даже если спящий режим прерывается сигналом, за исключением случаев, когда обработчик сигнала вызывает исключение ( объяснение см. В PEP 475 ).
Вы не можете ничего гарантировать относительно sleep (), за исключением того, что он, по крайней мере, будет делать все возможное, чтобы заснуть, пока вы ему сказали (сигналы могут убить ваш сон до того, как время истекло, и многое другое может заставить его работать длинный).
Конечно, минимум, который вы можете получить в стандартной настольной операционной системе, будет около 16 мс (детализация таймера плюс время до переключения контекста), но есть вероятность, что% отклонение от предоставленного аргумента будет значительным, когда вы пытаетесь спать на 10 миллисекунд.
Сигналы, другие потоки, содержащие GIL, планирование ядра, изменение скорости процессора и т. Д. - все это может нанести ущерб продолжительности вашего потока / процесса в режиме ожидания.
Проверено недавно на Python 3.7 в Windows 10. Точность составляла около 1 мс.
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()
Не используйте переменную для передачи аргумента sleep (), вы должны вставить вычисление непосредственно в sleep ()
И возвращение моего терминала
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 мс