I wrote a python script which makes calculation at every hour. I run this script with crontab scheduled for every hour. But there is one more thing to do;
Additionally, I should make calculation once a day by using the results evaluated at every hour. In this context, I defined a thread function which checks the current time is equal to the specified time (15:00 PM, once a day ). If it is, thread function is called and calculation made.
What I wanna ask here is; is this approach applicable ? I mean, running the first script at every hour using crontab, and calling the second function using thread function once a day.
Is there any other way of doing this ?
You may use python library sched.
It efficient way to schelude your operations.
You could do a script which runs all the time and just sleeps for one hour.
import time
hours_ran = 0
while True:
# your stuff here
time.sleep(3600)
hours_ran += 1
if hours_ran == 24:
# calculate stuff
hours_ran = 0
This is not necessarily better tho...
You can setup systemd to manage this process.
Related
So I need my program to run a task every given hour of a given day, I looked for a module that could easily do it and it exists, the schedule one, unfortunately we do not have it at my company's computer and I am not allowed to install anything, so I thought of something like this as a solution
import datetime
now = datetime.datetime.now()
while True:
if now.strftime("%d") == '09':
if now.strftime("%H") == '18':
do something
but it does not quite work as expected, if i Run the program at the schedulled time it runs normally, but if it's not, it does nothing when the time comes
what can I do?
You've defined now outside the loop at the start of the program. Once running, it never changes. Set now inside the loop, and consider using sleep to let this program not waste resources as much.
I am using python's sched module to run a task periodically, and I think I have come across a bug.
I find that it relies on the time of the system on which the python script is run. For example, let's say that I want to run a task every 5 seconds. If I forward the system time, the scheduled task will run as expected. However, if I rewind the system time to, say 1 day, then the next scheduled task will run in 5 seconds + 1 day.
If you run the script below and then change your system time by a few days back, then you can reproduce the issue. The problem can be reproduced on Linux and Windows.
import sched
import time
import threading
period = 5
scheduler = sched.scheduler(time.time, time.sleep)
def check_scheduler():
print time.time()
scheduler.enter(period, 1, check_scheduler, ())
if __name__ == '__main__':
print time.time()
scheduler.enter(period, 1, check_scheduler, ())
thread = threading.Thread(target=scheduler.run)
thread.start()
thread.join()
exit(0)
Anyone has any python solution around this problem?
From the sched documentation:
class sched.scheduler(timefunc, delayfunc)
The scheduler class defines a generic interface to scheduling events. It needs two functions to actually deal with the “outside
world” — timefunc should be callable without arguments, and return a
number (the “time”, in any units whatsoever). The delayfunc function
should be callable with one argument, compatible with the output of
timefunc, and should delay that many time units. delayfunc will also
be called with the argument 0 after each event is run to allow other
threads an opportunity to run in multi-threaded applications.
The problem you have is that your code uses time.time() as timefunc, whose return value (when called without arguments) is the current system time and is thus affected by re-winding the system clock.
To make your code immune to system time changes you'd need to provide a timefunc which doesn't depend on the system time, start/current timestamps, etc.
You can write your own function, for example one returning the number of seconds since your process is started, which you'd have to actually count in your code (i.e. don't compute it based on timestamp deltas). The time.clock() function might help, if it's based on CPU time counters, but I'm not sure if that's true or not.
There is a significant difference between my question and the given one. If I implement sleep as given on the link (which some people think my question is a duplicate of another one) then my whole app will hang for certain time. On the other hand I am looking for a scheduler so that my app will not hang but just after a certain period of time a .wav file will run. Meanwhile I would be able to do anything using my app. Hope that makes sense.
I am going to build an alarm clock. I think I can do this according to this Algorithm...
take current time using time.clock()
compare current time with the given time.
if current time is not given time then continue taking current time and compare whether current time is the given time or not.
if current time is the given time then play the .wav file.
The problem with this program is it will continuously run until the given time. So I am looking for better idea. Let's say if there is any Python module/class/function which can play a sound file on a given time. Is there any Python module/class/function which can wake up on a given time? Or my algorithm is used usually for all alarm clocks?
As far as I know there is not a good Python module to do this. What you are looking for though is a cron job. It allows you to schedule specific scripts to run at certain times. So your Python script would end up just being the code to play the .wav, and then you would need to create a cron job to tell your computer to execute that script at a certain time each day.
Have a look at the sched module.
Here's an example on how to use it:
import sched, time, datetime
def print_time():
print("The time is now: {}".format(datetime.datetime.now()))
# Run 10 seconds from now
when = time.time() + 10
# Create the scheduler
s = sched.scheduler(time.time)
s.enterabs(when, 1, print_time)
# Run the scheduler
print_time()
print("Executing s.run()")
s.run()
print("s.run() exited")
The time is now: 2015-06-04 11:52:11.510234
Executing s.run()
The time is now: 2015-06-04 11:52:21.512534
s.run() exited
I want to schedule a job (run a python script) everyday at a specific time till a specific date has been reached.
Researching on a lot of Pythonic schedulers, I thought that APScheduler was a good candidate to get around this.
This is an example snippet using APScheduler that starts a job and executes it every two hours after a specified date.
from datetime import datetime
from apscheduler.scheduler import Scheduler
# Start the scheduler
sched = Scheduler()
sched.start()
def job_function():
print "Hello World"
# Schedule job_function to be called every two hours
sched.add_interval_job(job_function, hours=2)
# The same as before, but start after a certain time point
sched.add_interval_job(job_function, hours=2, start_date='2010-10-10 09:30')
How to achieve the same and have a upper limit date after which the job should not be executed?
Any suggestions that revolve within and outside the APScheduler are most welcome.
Thanks in advance.
Use a cron job that executes your script every two hours (cron is made specifically for things like this). In your script, you just look up the system date and check, if it's smaller than your given date. If it's smaller, you execute the rest of your script, otherwise you quit.
You may also write additional code, so you get notified when the script is not actually executed anymore.
I eventually found the interval trigger can take an end_date.
You can pass arguments for the trigger to add_job with trigger='interval':
sched.add_job(job_function, trigger='interval', hours=2, end_date='2016-10-10 09:30')
I think you may be using an older version of the software.
I have a python program that I want to run every 10 seconds, just like cron job. I cannot use sleep in a loop because the time interval would become uncertain. The way I am doing it now is like this:
interval = 10.0
next = time.time()
while True:
now = time.time()
if now < next:
time.sleep(next - now)
t = Thread(target=control_lights,)
t.start()# start a thread
next += interval
It generates a new thread that executes the contro_lights function. The problem is that as time goes, the number of python process grows and takes memory/CPU. Is there any good way to do this? Thanks a lot
may be try use supervisord or god for this script? It is very simple to use and to control a number of you'r processes on UNIX-like operating system
Take a look at a program called The Fat Controller which is a scheduler similar to CRON but has many more options. The interval can be measured from the end of the previous run (like a for loop) or regularly every x seconds, which I think is what you want. Particularly useful in this case is that you can tell The Fat Controller what to do if one of the processes takes longer than x seconds:
run a new instance anyway (increase parallel processes up to a specified maximum)
wait for the previous one to finish
kill the previous one and start a new one
There should be plenty of information in the documentation on how to get it set up.
You can run a cron job every 10 seconds, just set the second param to '0/10'. It will run on 0, 10, 20 etc
#run every 10 seconds from mon-fri, between 8-17
CronTrigger(day_of_week='mon-fri', hour='8-17', second='0/10')