Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger a Python function exactly on the minute

I have a function that I want to trigger at every turn of the minute — at 00 seconds. It fires off a packet over the air to a dumb display that will be mounted on the wall.

I know I can brute force it with a while loop but that seems a bit harsh.

I have tried using sched but that ends up adding a second every minute.

What are my options?

like image 372
user2929831 Avatar asked Oct 28 '13 21:10

user2929831


People also ask

How do I run a function at a specific time in Python?

Schedule lets you run Python functions (or any other callable) periodically at pre-determined intervals using a simple, human-friendly syntax. Schedule Library is used to schedule a task at a particular time every day or a particular day of a week. We can also set time in 24 hours format that when a task should run.

How do I run a Python function every 5 minutes?

With the help of the Schedule module, we can make a python script that will be executed in every given particular time interval. with this function schedule. every(5). minutes.do(func) function will call every 5 minutes.

How do you call a function repeatedly in Python?

start() and stop() are safe to call multiple times even if the timer has already started/stopped. function to be called can have positional and named arguments.


5 Answers

You might try APScheduler, a cron-style scheduler module for Python.

From their examples:

from apscheduler.scheduler import Scheduler

# Start the scheduler
sched = Scheduler()
sched.start()

def job_function():
    print "Hello World"

sched.add_cron_job(job_function, second=0)

will run job_function every minute.

like image 194
Christian Ternus Avatar answered Oct 12 '22 12:10

Christian Ternus


What if you measured how long it took your code to execute, and subtracted that from a sleep time of 60?

import time

while True:
    timeBegin = time.time()

    CODE(.....)

    timeEnd = time.time()
    timeElapsed = timeEnd - timeBegin
    time.sleep(60-timeElapsed)
like image 24
Tizzee Avatar answered Oct 12 '22 11:10

Tizzee


The simplest solution would be to register a timeout with the operating system to expire when you want it to.

Now there are quite a few ways to do so with a blocking instruction and the best option depends on your implementation. Simplest way would be to use time.sleep():

import time

current_time = time.time()
time_to_sleep = 60 - (current_time % 60)
time.sleep(time_to_sleep)

This way you take the current time and calculate the amount of time you need to sleep (in seconds). Not millisecond accurate but close enough.

like image 4
immortal Avatar answered Oct 12 '22 13:10

immortal


APScheduler is the correct approach. The syntax has changed since the original answer, however.

As of APScheduler 3.3.1:

def fn():
    print("Hello, world")

from apscheduler.schedulers.background import BackgroundScheduler

scheduler = BackgroundScheduler()
scheduler.start()
scheduler.add_job(fn, trigger='cron', second=0)
like image 4
Daniel Jones Avatar answered Oct 12 '22 11:10

Daniel Jones


You can try Threading.Timer

See this Example

from threading import Timer

def job_function():
    Timer(60, job_function).start ()
    print("Running job_funtion")

It will print "Running job_function" every Minute

Edit: If we are critical about the time at which it should run

from threading import Timer
from time import time


def job_function():
    Timer(int(time()/60)*60+60 - time(), job_function).start ()
    print("Running job_funtion")

It will run exactly at 0th second of every minute.

like image 2
Anshuman Avatar answered Oct 12 '22 11:10

Anshuman