Run a python function every second

后端 未结 6 851
我寻月下人不归
我寻月下人不归 2020-12-16 08:08

What I want is to be able to run a function every second, irrelevant of how long the function takes (it should always be under a second). I\'ve considered a number of option

相关标签:
6条回答
  • 2020-12-16 08:45

    This will do it, and its accuracy won't drift with time.

    import time
    
    start_time = time.time()
    interval = 1
    for i in range(20):
        time.sleep(start_time + i*interval - time.time())
        f()
    
    0 讨论(0)
  • 2020-12-16 08:45

    if f() always takes less than a second then to run it on a one second boundary (without a drift):

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

    The idea is from @Dave Rove's answer to a similar question.

    To understand how it works, consider an example:

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

    At each step f() is called on a one second boundary (according to time.monotonic() timer). The errors do not accumulate. There is no drift.

    See also: How to run a function periodically in python (using tkinter).

    0 讨论(0)
  • 2020-12-16 08:47

    I would like to recommend the following code. You can replace the True with any condition if you want.

    while True:
    time.sleep(1) #sleep for 1 second
    func()    #function you want to trigger
    

    Tell me if it works.

    0 讨论(0)
  • 2020-12-16 08:49

    The approach using a threading.Timer (see code below) should in fact not be used, as a new thread is launched at every interval and this loop can never be stopped cleanly.

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

    If you want a background loop it is better to launch a new thread that runs a loop as described in the other answer. Which is able to receive a stop signal, s.t. you can join() the thread eventually.

    This related answer seems to be a great starting point to implement this.

    0 讨论(0)
  • 2020-12-16 08:50

    How about this: After each run, sleep for (1.0 - launch interval) seconds. You can change the terminate condition by changing while True:. Although if the your function takes more than 1 second to run, this will go wrong.

    from time import time, sleep
    
    while True:
        startTime = time()
        yourFunction()
        endTime = time()-startTime
        sleep(1.0-endTime)
    
    0 讨论(0)
  • 2020-12-16 08:59

    Threading may be a good choice. The basic concept is as follows.

    import threading
    
    def looper():    
        # i as interval in seconds    
        threading.Timer(i, looper).start()    
        # put your action here
        foo()
    
    #to start 
    looper()
    
    0 讨论(0)
提交回复
热议问题