In Python, how can I put a thread to sleep until a specific time?
Here's a half-ass solution that doesn't account for clock jitter or adjustment of the clock. See comments for ways to get rid of that.
import time
import datetime
# if for some reason this script is still running
# after a year, we'll stop after 365 days
for i in xrange(0,365):
# sleep until 2AM
t = datetime.datetime.today()
future = datetime.datetime(t.year,t.month,t.day,2,0)
if t.hour >= 2:
future += datetime.timedelta(days=1)
time.sleep((future-t).total_seconds())
# do 2AM stuff
How to sleep until a specific time YYYY-MM-DD HH:MM:SS?
Easy, calculate how long it is, and sleep the time.
You can calculate how long it takes until your wakeup time is reached and sleep for the delta time.
Python can calculate with time intervals. If you subtract one timestamp from another, then you get a datetime.timedelta
:
import datetime
import time
target = datetime.datetime(2019,1,20,12,0,0)
now = datetime.datetime.now()
delta = target - now
if delta > datetime.timedelta(0):
print('will sleep: %s' % delta)
time.sleep(delta.total_seconds())
print('just woke up')
of course, you can put that in a function:
import datetime
import time
target = datetime.datetime(2019,1,20,12,0,0)
def sleep_until(target):
now = datetime.datetime.now()
delta = target - now
if delta > datetime.timedelta(0):
time.sleep(delta.total_seconds())
return True
sleep_until(target)
You can check the return value: only if it slept, it returns True.
BTW: it's OK, to use a date in the past as target. This will generate a negative number of seconds. Sleeping a negative value will just not sleep.
if your time is a string, use this:
target = datetime.datetime.strptime('20.1.2019 20:00:00', '%d.%m.%Y %H:%M:%s')
or
target = datetime.datetime.strptime('2019-1-20 20:00:00', '%Y-%m-%d %H:%M:%s')
Python Sleep Until a Certain Time
Solution with a sleep-wait loop:
import datetime
import time
target_time = datetime.datetime(2017, 3, 7, 3) # 3 am on 3 July 2017
while datetime.datetime.now() < target_time:
time.sleep(10)
print('It is 3am, now running the rest of the code')
If instead of sleeping, you want to do other work, consider using threading.Timer or the sched module.
Sleeping a Thread until certain time in Python
Don't use thread sleeping. This is absolutely the wrong approach to the problem. If you don't want to use crons (I assume you mean literal linux cron jobs), use something like this https://docs.python.org/2/library/sched.html
Sleep until a certain amount of time has passed
It sounds like don't want to sleep for 30 second but rather pad the time it takes to perform an activity with a sleep so that it always takes 30 seconds.
import time
from datetime import datetime, timedelta
wait_until_time = datetime.utcnow() + timedelta(seconds=30)
move_motor()
seconds_to_sleep = (wait_until_time - datetime.utcnow()).total_seconds()
time.sleep(seconds_to_sleep)
if you are going to be doing this in multiple places you can create a decorator that you can apply to any function
import functools
import time
from datetime import datetime, timedelta
def minimum_execution_time(seconds=30)
def middle(func)
@functools.wraps(func)
def wrapper(*args, **kwargs):
wait_until_time = datetime.utcnow() + timedelta(seconds=seconds)
result = func(*args, **kwargs)
seconds_to_sleep = (wait_until_time - datetime.utcnow()).total_seconds()
time.sleep(seconds_to_sleep)
return result
return wrapper
You can then use this like so
@minimum_execution_time(seconds=30)
def move_motor(...)
# Do your stuff
time.sleep -- sleeps thread or process?
It blocks the thread. If you look in Modules/timemodule.c in the Python source, you'll see that in the call to floatsleep()
, the substantive part of the sleep operation is wrapped in a Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS block, allowing other threads to continue to execute while the current one sleeps. You can also test this with a simple python program:
import time
from threading import Thread
class worker(Thread):
def run(self):
for x in xrange(0,11):
print x
time.sleep(1)
class waiter(Thread):
def run(self):
for x in xrange(100,103):
print x
time.sleep(5)
def run():
worker().start()
waiter().start()
Which will print:
>>> thread_test.run()
0
100
>>> 1
2
3
4
5
101
6
7
8
9
10
102
delay a task until certain time
Think you can also use the following code:
from datetime import datetime, time
from time import sleep
def act(x):
return x+10
def wait_start(runTime, action):
startTime = time(*(map(int, runTime.split(':'))))
while startTime > datetime.today().time(): # you can add here any additional variable to break loop if necessary
sleep(1)# you can change 1 sec interval to any other
return action
wait_start('15:20', lambda: act(100))
Dynamic time sleep until new minute starts with HH:MM:01 second
You can sleep the necessary amount of remaining time up to a minute by marking the time when the work starts and finishes, e.g.
import time
import random
while True:
start_time = time.time()
time.sleep(random.randint(2,5)) # do some work
worked_time = time.time() - start_time
print("worked for", worked_time)
wait_to_align = 60.0 - worked_time % 60.0
print(f"sleep {wait_to_align} to align to a minute")
time.sleep(wait_to_align)
produces
worked for 3.002328634262085
sleep 56.997671365737915 to align to a minute
worked for 5.003056764602661
sleep 54.99694323539734 to align to a minute
...
Related Topics
No Multiline Lambda in Python: Why Not
Cannot List Ftp Directory Using Ftplib - But Ftp Client Works
Typeerror: Cannot Create a Consistent Method Resolution Order (Mro)
Matplotlib Figure Facecolor (Background Color)
Can Multiprocessing Process Class Be Run from Idle
Attributeerror: 'List' Object Has No Attribute 'Click' - Selenium Webdriver
How to Create an SQL View with SQLalchemy
Redirect While Passing Arguments
Why Can't I Change Only a Single Element in a Nested List in Python
Any Reason Not to Use '+' to Concatenate Two Strings
Get All Object Attributes in Python
Is Tensorflow Compatible with a Windows Workflow
Unicodeencodeerror: 'Ascii' Codec Can't Encode Character '\Xe9' - -When Using Urlib.Request Python3
How to Set Selenium Webdriver from Headless Mode to Normal Mode Within the Same Session