2016-11-12 3 views
1

Привет У меня есть вопрос относительно функции time.sleep() в python 3. То, что я пытаюсь сделать, это периодически циклически перебирать список значений со скоростью 0,001 второй/точка. Он отлично работает с 0,01 или выше. Но при 0,001 или меньше, скорость сильно зависит от открытия или отключения других программ. Например, у меня есть список из 100 баллов и пробег с 0,001 секунды за точку. Тогда для его завершения потребуется приблизительно 100 * 0,001 = 0,1 секунды. Однако, когда я запускаю код, для завершения требуется более 1 секунды. Затем я включаю Google Chrome и открываю переполнение стека или веб-сайты quora, затем он работает с нужной скоростью около 0,11 секунды. Мне интересно, есть ли какие-либо решения для устранения этой проблемы или альтернативы time.sleep(), на которые другие программы не будут затронуты. Вот мой код для тестирования time.sleep().python 3 time.sleep() замедляет работу или ускоряется другими программами

import time 
from timeit import default_timer as timer 
import threading 

my_points = [1,2,3,4,5,6,7,8,9,10, 
      11,12,13,14,15,16,17,18,19,20, 
      21,22,23,24,25,26,27,28,29,30, 
      31,32,33,34,35,36,37,38,39,40, 
      41,42,43,44,45,46,47,48,49,50, 
      51,52,53,54,55,56,57,58,59,60, 
      61,62,63,64,65,66,67,68,69,70, 
      71,72,73,74,75,76,77,78,79,80, 
      81,82,83,84,85,86,87,88,89,90, 
      91,92,93,94,95,96,97,98,99,100,] 

def execute(): 
    while True: 
     start = timer() 
     for i in my_points: 
     print (i, flush = True) 
     time.sleep(0.001) #Problem is here 

     end = timer() 
     print ("Total time run per cycle: ", end - start) 
     time.sleep(2) #To read the time 

execute() 
+0

Какую проблему вы на самом деле пытаетесь решить здесь, которая требует точного сна ровно миллисекунды? – kindall

+0

не точная миллисекунда. Я могу быть немного, но не в десять раз больше. Это то, о чем я беспокоюсь. –

+0

Опять же, какую проблему вы пытаетесь решить с помощью этого подхода? Возможно, есть лучший способ сделать это в целом. – kindall

ответ

0

ручной ввод для time.sleep

time.sleep (сек)

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

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

дает представление о том, что фактическое время сна приблизит только требуемое время. Я отдельно прочитал, что разрешение на Windows составляет 1/60 с, хотя я не знаю, верно ли это.

Вы можете сделать намного лучше, используя функцию tkinter root.after. Когда я бегу следующее в IDLE

import tkinter as tk 
from time import perf_counter as timer 

root = tk.Tk() 
n = 1000 
def tick(): 
    global n 
    if n: 
     #print(n) 
     root.after(1, tick) 
     n -= 1 
    else: 
     print(timer() - start) 
     root.quit() 

root.after(1, tick) 
start = timer() 
root.mainloop() 

выход повторяемостью чуть менее 1,05 секунды, очень близко к цели 1,00. Если я раскомментирую заявление о тике печати, время составляет 4,2 секунды. В IDLE печать проходит через сокет в отдельный процесс, который немного медленный. Запуск в командной строке Windows составляет 1000 секунд. Я ожидаю, что речь идет о том, что вы получите вывод на последовательный пост, если получатель может не отставать от потока.

EDIT Можно было сделать что-то подобное с относительно новым модулем asyncio, и с меньшими усилиями использовать даже новый синтаксис async for. Но у меня нет необходимых знаний.

+0

Очень интересное решение. Я побежал, и это сработало. Поскольку мое приложение уже применяет tkinter, мне нужно выяснить, как это сделать для определенного фрейма, который содержит кнопку для запуска этой функции. Спасибо! –

+0

Я считаю, что вы можете просто опустить root-модуль на уровне модуля. После этого вызовите команду «tick». Или вызовите его из функции команды кнопки после выполнения настройки. –

+0

Я снова столкнулся с той же проблемой, даже с функцией tk after(). Он работает очень хорошо, когда Chrome включен. очень странно. –

0

В обычных функциях сна в POSIX и, предположительно, в Windows также гарантируется спящий режим, по крайней мере, на указанную продолжительность (если только прерывание не было ранее сигналом), но они могут спать произвольно долго после указанной продолжительности в зависимости от того, когда Планировщик потоков ОС решает разбудить поток.

Вы можете попробовать запустить свою программу с помощью политики планирования в реальном времени, например. в случае, если вы используете Linux, см. https://docs.python.org/3/library/os.html#os.sched_setscheduler и http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html.

Смежные вопросы