Need a way to pause a script for 2 minutes after letting it run for 10 minutes first, and then have this process repeat itself. I need the script itself to continue running throughout the 10 minutes.
I tried using threading but found that it didn't actually pause the the rest of the script.
EDIT: Added code to give perspective. Hopefully this helps to explain my issue.
Your code has a nice loop where you can implant the pause, like so:
from datetime import datetime, timedelta
...
def start():
lastsleep = datetime.now() # <-- new
while True:
openBank()
gear()
invCheck()
timer = random.uniform(33, 37)
print("Sleep time: %s" % timer)
time.sleep(timer)
if (datetime.now() - lastsleep) > timedelta(minutes=10): # <-- new
time.sleep(2*60)
lastsleep = datetime.now()
Note that this will not sleep exactly after 10 minutes, but whenever 10 minutes are over and it reaches the checkpoint. This may be 10:12 or 13:47 minutes, depending on what the other code (openBank(), gear() etc.) does before.
Answer before code was shown:
The problem is: we have no information on how your code looks like.
If you have
something = getSomething()
something.DoSomeVeryExpensiveOperation() # takes 25 minutes
there's no good way to interrupt or pause that method after 10 minutes.
The only way I can think of as a generic method is like this:
use multiprocessing
monitor the process from outside
after 10 minutes, suspend all threads of the process
sleep 2 minutes
resume all threads of the process
Before you do that, you should know why you should never suspend a thread
Related
I am using below code to excute a python script every 5 minutes but when it executes next time its not excecuting at excact time as before.
example if i am executing it at exact 9:00:00 AM, next time it executes at 9:05:25 AM and next time 9:10:45 AM. as i run the python script every 5 minutes for long time its not able to record at exact time.
import schedule
import time
from datetime import datetime
# Functions setup
def geeks():
print("Shaurya says Geeksforgeeks")
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print("Current Time =", current_time)
# Task scheduling
# After every 10mins geeks() is called.
schedule.every(2).minutes.do(geeks)
# Loop so that the scheduling task
# keeps on running all time.
while True:
# Checks whether a scheduled task
# is pending to run or not
schedule.run_pending()
time.sleep(1)
Is there any easy fix for this so that the script runs exactly at 5 minutes next time.
please don't suggest me to use crontab as I have tried crontabs ut not working for me.
I am using python script in different os
your geeks function will cost time to execute,and schedule job start calculate 5min after geeks done,that's why long time its not able to record at exact time.
if you want your function run at exact time,you can trying this:
# After every 10mins geeks() is called.
#schedule.every(2).minutes.do(geeks)
for _ in range(0,60,5):
schedule.every().hour.at(":"+str(_).zfill(2)).do(geeks)
# Loop so that the scheduling task
It's because schedule does not account for the time it takes for the job function to execute. Use ischedule instead. The following would work for your task.
import ischedule
ischedule.schedule(geeks, interval=2*60)
ischedule.run_loop()
I have a program running on a Raspberry Pi, and I want to pull some data from a thermometer every 15 minutes at 0, 15, 30 and 45 minutes past the hour.
I have tried this using a while loop, I previously used time.sleep(900) effectively, but this sometimes drifted away from 0, 15, 30 and 45 minutes past the hour.
At the moment I currently have this;
from datetime import datetime
def run(condition):
while condition == True:
if (datetime.now().minute == (0 or 15 or 30 or 45)):
#perform some task
temperature_store()
For sake of simplicity I have not got into what temperature_store() does, but it reads the temperature from a sensor plugged into the Pi and then prints it.
I want temperature_store() to occur every 15 minutes, but currently, it is happening every second.
I am aware that it is probably because I have the logic/syntax of the while loop wrong, but I cannot figure it out. (Do not have much experience with python scripts and delays in time).
There's two ways to do this: the 'easy' way, and the stable way.
The easy way is simply to do the following:
from datetime import datetime
from time import sleep
def run(condition):
while datetime.now().minute not in {0, 15, 30, 45}: # Wait 1 second until we are synced up with the 'every 15 minutes' clock
sleep(1)
def task():
# Your task goes here
# Functionised because we need to call it twice
temperature_store()
task()
while condition == True:
sleep(60*15) # Wait for 15 minutes
task()
This essentially waits until we are synced up with the correct minute, then executes it, and simply waits 15 minutes before looping. Use it if you wish, it's the simplest way in pure Python. The issues with this are countless, however:
It syncs up with the minute, not the second
It's machine dependent, and may give incorrect readings on some machines
It needs to run continuously!
The second method is to use cron-jobs, as suggested in the comments. This is superior because:
It uses system-level events, not timers, so we can assure the best possible accuracy
Since we're not waiting, there's no room for error
It only runs the function once it gets the aforementioned event setter.
So, to use, simply (assuming you're on Linux):
from crontab import CronTab
cron = CronTab(user='username') # Initialise a new CronTab instance
job = cron.new(command='python yourfile.py') # create a new task
job.minute.on(0, 15, 30, 45) # Define that it should be on every 0th, 15th, 30th and 45th minute
cron.write() # 'Start' the task (i.e trigger the cron-job, but through the Python library instead
(obviously, configure username appropriately)
In yourfile.py, in the same path, simply put your code for temperature_store().
I hope this helps. Obviously, go with the first methods or even the suggestions in the comments if you prefer, but I just felt that the entire loop structure was a bit too fragile, especially on a Raspberry Pi. This should hopefully be something more stable and scalable, should you want to hook up other IoT things to your Pi.
I did the module test in case of the program that prints seconds every 15 seconds.
The below code does not contain sleep().
You can change second to minute in below code to do tasks every 15 minutes.
from datetime import datetime
while True:
a = datetime.now().second
if (a % 15) == 0: # every 15 seconds
print(a) # ---- To do something every 15 seconds ---- #
while True: # discard any milliseconds or duplicated 15 seconds
a = datetime.now().second
if (a % 15) is not 0:
break
But I think that cron or any other schduler modules are good choices.
I have come up with the following answer, using some of the logic from #geza-kerecsenyi 's answer
def run():
first = True
while first == True:
second = True
while second == True:
if datetime.now().minute == 0 or datetime.now().minute ==15 or datetime.now().minute ==30 or datetime.now().minute == 45:
action()
sleep(899)
I am not sure which of these is better in terms of CPU or which is more effective to run, but the logic seems sound on both.
[#geza-kerecsenyi will mark your answer as correct]
I'm new to explore how to do this in python. What I want to do is run a function every business day at a specific time, e.g., say at 14:55, just 5 minutes before the stock market closes in China. This function will pull some data from a stock market data feeding API and do some simple calculations to generate a signal(-1 means to short, +1 means to long, 0 means don't do anything). I'm not sending the signal yet to make a trade now. I'm just saving the signals everyday to a file locally. Thus, I might be able to collect the signals for 2 weeks or any time I feel like to stop this scheduler.
I notice that APScheduler module being suggested quite often. But I tried it, didn't find a way to make the scheduler stop running 2 weeks after. I only find ways to set up a scheduler to run, maybe every 10 minutes, but it will just keep running a specified function every 10 minutes and can't be stopped programmally, but only through pressing Ctrl+C? For example, I want to run a function every 10 minutes for 6 times, in APScheduler, I didn't see anyway to specify the '6 times' argument. Or I want to run a function every 10 minutes until 1 hour later. I didn't see the '1 hour later' or 'at 16:30' argument either. How to do it?
Currently, I'm doing it this way:
def test_timer():
'''
Uses datetime module.
'''
running = 1
stop_time = datetime.now() + timedelta(seconds=60)
while running:
print('I\'m working...')
time.sleep(5)
running = datetime.now() < stop_time
print('Goodbye!')
Edited: I'm using python 3.6 in Windows 10.
Try this example
from datetime import datetime
from apscheduler.schedulers.background import BackgroundScheduler
def job_function():
print("Hello World")
sched = BackgroundScheduler()
# Schedule job_function to be called every 1 second
# FIXME: Do not forget to change end_date to actual date
sched.add_job(job_function, 'interval', seconds=1, end_date="2017-09-08 12:22:20")
sched.start()
Update #1
from apscheduler.schedulers.background import BackgroundScheduler
def job_function():
print("Hello World")
# Here, you can generate your needed days
dates = ["2017-09-08 13:30:20", "2017-09-08 13:31:20", "2017-09-08 13:32:20"]
sched = BackgroundScheduler()
for date in dates:
sched.add_job(job_function, "date", next_run_time=date)
sched.start()
Looks like a problem for crontab in Linux or Task Scheduler in Windows.
I have a cron job that runs at 12, 12:30,1, 1:30. So every half hour intervals on the clock. I want to run a thread in my python code whenever the cron job runs.
I have seen examples where to run a timer every x seconds/mintues.But if I start my python code at 1:15pm for example if I set a timer for every 30 mins, the next time it will run is at 1:45pm. I want to thread to run at 1:30pm though. Is that possible?
Almost everything is possible, the real question is why do you want to do this? Keep in mind that cron scheduler won't necessarily execute jobs at precise times and furthermore, checking the time in Python won't necessarily correspond to cron's time, so if you need to execute something in your Python code after a cron job is executed, you cannot rely on measuring timings in Python - you actually need to 'communicate' from your cron job to your Python script (the easiest would be using datagram sockets)
But, if you want to simulate cron scheduler in Python, one way to do it is to use the datetime module to get the current time and then calculate the amount of time.sleep() you need before your command fires again, e.g.:
def schedule_hourly_task(task, minute=0):
# get hourly offset in seconds in range 1-3600
period = ((60 + minute) % 60) * 60 or 3600
while True:
# get current time
current = datetime.datetime.now()
# count number of seconds in the current hour
offset = (current - current.replace(minute=0, second=0, microsecond=0)).total_seconds()
# calculate number of seconds til next period
sleep = period - offset % period
if offset + sleep > 3600: # ensure sleep times apply to full hours only
sleep += 3600 % period
# sleep until the next period
time.sleep(sleep)
# run the task, break the loop and exit the scheduler if `False` is returned
if not task():
return
Then you can use use it to run whatever task you want at any full_hour + minute offset. For example:
counter = 0
def your_task():
global counter
counter += 1
if counter > 2:
return False
return True
schedule_hourly_task(your_task, 15)
And it will execute your_task() function every 15 minutes until your_task() returns False - in this case at hh:15, hh:30 and hh:45 before exiting. In your case, calling schedule_hourly_task(your_task, 30) will call the your_task() function every full 30 minutes for as long as your_task() returns True.
How do I have a part of python script(only a method, the whole script runs in 24/7) run everyday at a set-time, exactly at every 20th minutes? Like 12:20, 12:40, 13:00 in every hour.
I can not use cron, I tried periodic execution but that is not as accurate as I would... It depends from the script starting time.
Module schedule may be useful for this. See answer to
How do I get a Cron like scheduler in Python? for details.
You can either put calling this method in a loop, which would sleep for some time
from time import sleep
while True:
sleep(1200)
my_function()
and be triggered once in a while, you could use datetime to compare current timestamp and set next executions.
import datetime
function_executed = False
trigger_time = datetime.datetime.now()
def set_trigger_time():
global function executed = False
return datetime.datetime.now() + datetime.timedelta(minutes=20)
while True:
if function_executed:
triggertime = set_trigger_time()
if datetime.datetime.now() == triggertime:
function_executed = True
my_function()
I think however making a system call the script would be a nicer solution.
Use for example redis for that and rq-scheduler package. You can schedule tasks with specific time. So you can run first script, save to the variable starting time, calculate starting time + 20 mins and if your current script will end, at the end you will push another, the same task with proper time.