Насколько точным является python time.sleep ()? - PullRequest
79 голосов
/ 16 июля 2009

Я могу дать ему числа с плавающей запятой, такие как

time.sleep(0.5)

но насколько это точно? Если я дам это

time.sleep(0.05)

Это действительно будет спать около 50 мс?

Ответы [ 9 ]

67 голосов
/ 16 июля 2009

Точность функции time.sleep зависит от точности сна вашей базовой ОС. Для нереальных операционных систем, таких как стандартная Windows, наименьший интервал, в течение которого вы можете спать, составляет около 10-13 мс. Я видел точные сны в течение нескольких миллисекунд того времени, когда они превышали минимум 10-13 мс.

Обновление: Как упомянуто в документах, цитируемых ниже, обычно делать сон в цикле, который обязательно вернется ко сну, если он вас рано разбудит.

Я также должен упомянуть, что если вы работаете в Ubuntu, вы можете попробовать псевдо-ядро реального времени (с набором патчей RT_PREEMPT), установив пакет ядра rt (по крайней мере, в Ubuntu 10.04 LTS).

РЕДАКТИРОВАТЬ: Исправление ядра Linux не в реальном времени имеют минимальный интервал ожидания намного ближе к 1 мс, чем 10 мс, но он изменяется недетерминированным образом.

49 голосов
/ 12 апреля 2013

Люди совершенно правы относительно различий между операционными системами и ядрами, но я не вижу никакой детализации в Ubuntu, и я вижу гранулярность 1 мс в MS7. Предлагая другую реализацию time.sleep, а не просто другую частоту тиков. Между прочим, более детальная проверка предполагает гранулярность в 1 мкс в Ubuntu, но это связано с функцией time.time, которую я использую для измерения точности. Linux and Windows typical time.sleep behaviour in Python

25 голосов
/ 16 июля 2009

Из документации :

С другой стороны, точность time() и sleep() лучше чем их Unix-эквиваленты: времена выражается в виде чисел с плавающей запятой, time() возвращает самое точное время доступно (с использованием Unix gettimeofday где доступно), и sleep() будет принять время с ненулевой дробью (Unix select используется для реализации это, где доступно).

И , более конкретно w.r.t. sleep()

Приостановить исполнение на заданный номер секунд. Аргумент может быть число с плавающей запятой для обозначения более точное время сна. Настоящий время приостановки может быть меньше запрашивается, потому что любой пойманный сигнал прекратит sleep() следующие выполнение ловли этого сигнала рутина. Также время приостановки мая быть длиннее , чем запрашивает произвольное количество из-за планирование другой деятельности в система.

16 голосов
/ 05 июня 2015

Вот мое продолжение ответа Уилберта: то же самое для Mac OS X Yosemite, так как он еще не упоминался. Sleep behavior of Mac OS X Yosemite

Похоже, большую часть времени он спит примерно в 1,25 раза больше времени, которое вы запрашиваете, а иногда спит от 1 до 1,25 раза больше времени, которое вы запрашиваете. Он почти никогда (~ дважды из 1000 образцов) не спит более, чем в 1,25 раза больше времени, которое вы запрашиваете.

Также (не показано явно) отношение 1.25, кажется, держится довольно хорошо, пока вы не опускаетесь ниже примерно 0,2 мс, после чего оно начинает становиться немного размытым. Кроме того, кажется, что фактическое время устанавливается примерно на 5 мс дольше, чем вы запрашиваете, после того, как запрошенное время превышает 20 мс.

Опять же, похоже, что это совершенно другая реализация sleep() в OS X, чем в Windows или в любом другом ядре Linux, которое использовал Уилберт.

15 голосов
/ 16 июля 2009

Почему бы вам не узнать:

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.

4 голосов
/ 25 апреля 2018

Небольшая поправка, некоторые люди упоминают, что сон может быть прекращен рано сигналом. В 3.6 документах написано:

Изменено в версии 3.5: функция теперь спит не менее секунд, даже если сон прерывается сигналом, за исключением случая, когда обработчик сигнала возникает исключение (см. PEP 475 для обоснования).

2 голосов
/ 16 июля 2009

Вы не можете ничего гарантировать в отношении сна (), за исключением того, что он, по крайней мере, приложит максимум усилий, чтобы спать, пока вы говорите (сигналы могут убить ваш сон до истечения времени, и многое другое может заставить его работать долго).

Конечно, минимальный уровень, который вы можете получить в стандартной операционной системе настольного компьютера, составит около 16 мс (гранулярность таймера плюс время для переключения контекста), но есть вероятность, что отклонение в% от предоставленного аргумента будет значительным, когда вы Пытаешься спать 10с миллисекунд.

Сигналы, другие потоки, удерживающие GIL, веселье в планировании ядра, снижение скорости процессора и т. Д. - все это может привести к хаосу в течение времени, в течение которого ваш поток / процесс фактически спит.

0 голосов
/ 12 января 2019
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 ────────────────────

0 голосов
/ 31 июля 2018

Недавно протестировано на Python 3.7 на Windows 10. Точность была около 1 мс.

...