Вопрос по python – Запускать функцию python каждую секунду

2

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

Если я просто использую функцию задержки, она не будет учитывать время, необходимое для выполнения функции.

Если я измерю время функции, а затем вычту это из секунды и составлю остаток в задержке, то это не будет принимать во внимание вычисления времени.

Я попытался использовать threading.timer (я не уверен насчет входов и выходов того, как это работает), но, похоже, он работал медленнее, чем 1.

Вот код, который я пробовал для тестирования threading.timer:

def update(i):
    sys.stdout.write(str(i)+'\r')
    sys.stdout.flush()
    print i
    i += 1
    threading.Timer(1, update, [i]).start()

Есть ли способ сделать это независимо от того, сколько времени занимает функция?

Еще одно мое решениеstackoverflow.com/a/10718961/709852 должен работать для этого. На самом деле, решение лучше подходит, так как временное разрешение кажется ниже, и оно, вероятно, будет работать на разных платформах. Henry Gomersall
Вы хотите, чтобы это было в фоновом потоке или в основном потоке? moooeeeep

Ваш Ответ

6   ответов
0
import time

lastSecond = 0
while True:
    while time.time() % 1 > 0.1:
        time.sleep(0.1)
    now = int(time.time())
    if now % 60 != lastSecond:
        print now
        lastSecond = now % 60
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
4

import time

start_time = time.time()
interval = 1
for i in range(20):
    time.sleep(start_time + i*interval - time.time())
    f()
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
1

(1.0 - launch interval) секунд. Вы можете изменить условие завершения, изменивwhile True:, Хотя если ваша функция запускается более 1 секунды, это пойдет не так.

from time import time, sleep

while True:
    startTime = time()
    yourFunction()
    endTime = time()-startTime
    sleep(1.0-endTime)
6

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

# as seen here: https://stackoverflow.com/a/3393759/1025391
def update(i):
  threading.Timer(1, update, [i+1]).start()
  # business logic here

Если вам нужен фоновый цикл, лучше запустить новый поток, который запускает цикл, как описано в другом ответе. Который способен принимать сигнал остановки, с.т. вы можетеjoin() нить в конце концов.

Этот связанный ответ кажется, хорошая отправная точка для реализации этого.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededaccording to this comment
Error: User Rate Limit Exceeded
1

едующем.

import threading

def looper():    
    # i as interval in seconds    
    threading.Timer(i, looper).start()    
    # put your action here
    foo()

#to start 
looper()
1

f() всегда требуется меньше секунды, чтобы запустить его на границе в одну секунду (без смещения):

import time

while True:
    time.sleep(1 - time.monotonic() % 1))
    f()

Идея отОтвет @Dave Rove на аналогичный вопрос.

Чтобы понять, как это работает, рассмотрим пример:

time.monotonic() returns 13.7 and time.sleep(0.3) is called f() is called around (±some error) 14 seconds (since time.monotonic() epoch) f() is run and it takes 0.1 (< 1) seconds time.monotonic() returns around 14.1 second and time.sleep(0.9) is called the step 2. is repeated around 15 seconds since time.monotonic() epoch f() is run and it, takes 0.3 (< 1) seconds (note: the value is different from the step 2.) time.monotonic() returns around 15.3 and time.sleep(0.7) is called f() is called around 16 seconds and the loop is repeated.

На каждом шагуf() вызывается на одной второй границе (согласноtime.monotonic() таймер). Ошибки не накапливаются. Там нет дрейфа.

Смотрите также:Как периодически запускать функцию в python (используя tkinter).

Похожие вопросы