How would I execute some code after a set number of milliseconds?
I only want to execute it once.
Thanks
There's the pygame.time.set_timer(eventid, milliseconds) function, which generates an event with id eventid on the event queue every milliseconds milliseconds, which you can then handle however you like. You can stop the event from being generated again by calling pygame.time.set_timer(eventid, 0).
SDL has an SDL_AddTimer function that does exactly what you want -- you pass it a callback function to be executed after some delay, but from the documentation I can't really find the pygame equivalent.
For a python solution, you can use the threading.Timer class.
Just have a look into the module sched — Event scheduler. The examples in the link are pretty neat to get you started
For python solution setTimeout equivalent would be:
import threading
def set_timeout(func, sec):
t = None
def func_wrapper():
func()
t.cancel()
t = threading.Timer(sec, func_wrapper)
t.start()
def hello():
print "Hello, world!"
set_timeout(hello, 0.1) # This is 0.1s = 100ms
Related
I'm trying to implement a decorator that allows to limit the rate with which a function is executed.
I would like the decorator to start a timer when the function is called. If the function is called before the timer runs out, I'd like to cancel the previous call and restart the timer. When the timer ends, the function should run.
I've serched around and found this decorator. However, this decorator stops the execution of the program while the timer is running, which is something I need to avoid.
How can I achieve this?
this is rather complicated, but a simple idea is to start a timer thread and cancel it if the function is called again and start another timer thread.
now we need somewhere to store this timer ... so a dictionary should suffice, and to allow the user to choose the delay, we will just do a double wrap of functions.
from threading import Timer
from functools import wraps
import time
functions_store = {}
def main_decorator(interval):
def sub_decorator(fun):
function_id = id(fun) # since no two objects have the same id
#wraps(fun)
def new_fun(*args,**kwargs):
if function_id in functions_store:
functions_store[function_id].cancel() # cancel old timer
new_timer = Timer(interval,fun,args=args,kwargs=kwargs) # make new timer
functions_store[function_id] = new_timer # store timer to stop it later
new_timer.start()
return new_fun
return sub_decorator
#main_decorator(1) # must be called again before 1 second passes.
def func_to_run():
print("hi")
func_to_run()
time.sleep(0.5)
func_to_run()
the word "hi" will be printed after 1.5 seconds instead of 1 second because we called the function again before it fired the first time.
I wanted to run a function repeating itself while my main code (I guess it is called main thread) is still running so I did this, there is probably a better way of doing this but I am new to coding and python so I have no idea what am I doing.
import threading
import time
def x():
print("hey")
time.sleep(1)
x()
t = threading.Thread(target=x)
t.daemon = True
t.start()
when I make daemon False it repeats itself but when I stop the program I get an error
CPython (the reference implementation of Python) does not implement Tail Call Optimization (TCO).¹ This means you can't run excessive recursion since it is limited and you would get a RuntimeError when you hit this limit.
sys.getrecursionlimit() # 3000
So instead of calling x() from within x() again, make a while True-loop within x():
import threading
import time
def x():
while True:
print("hey")
time.sleep(1)
t = threading.Thread(target=x, daemon=True)
t.start()
time.sleep(10) # do something, sleep for demo
¹ Stackless Python would be a Python implementation without recursion limit.
I have struggled with this question for about a week -- time to ask someone who can bang out an answer in a couple minutes.
I am trying to run a python program once every 10 seconds. There are a lot of questions of this sort : Use sched module to run at a given time, Python threading.timer - repeat function every 'n' seconds, How to execute a function asynchronously every 60 seconds in Python?
Normally the solutions using sched or time.sleep would work, but I am trying to start a scheduled process from within cmd2, which is already running in a while False loop. (When you exit cmd2, it exits this loop).
Because of this, when I start a function to repeat every 10 seconds, I enter another loop nested within cmd2 and I am unable to enter cmd2 commands. I can only get back to cmd2 by exiting the sub-loop that is repeating the function, and thus the function stops repeating.
Evidently threading will solve this problem. I have tried threading.Timer without success. Perhaps the real problem is that I do not understand threads or multiprocessing.
Here is an example of code that is roughly isomorphic to the code I'm using, using sched module, which I got to work:
import cmd2
import repeated
class prompt(cmd2.Cmd):
"""this lets you enter commands"""
def default(self, line):
return cmd2.Cmd.default(self, line)
def do_exit(self, line):
return True
def do_repeated(self, line):
repeated.func_1()
Where repeated.py looks like this:
import sched
import time
def func_2(sc):
print 'doing stuff'
sc.enter(10, 0, func_2, (sc,))
def func_1():
s = sched.scheduler(time.time, time.sleep)
s.enter(0, 0, func_2, (s,))
s.run()
http://docs.python.org/2/library/queue.html?highlight=queue#Queue
Can you instance a Queue object outside of cmd2? There can be one thread that watches the queue and takes jobs from it at periodic intervals; while cmd2 is free to run or not run. The thread that processes the queue, and the queue object itself need to be in the outer scope, of course.
To schedule something at a particular time, you can insert a tuple which has the target time in it. Or you can have the thread just check at regular intervals, if that's good enough.
[Edit, if you have a process that is intended to repeat, you can have it requeue itself at the end of it's operation.]
As soon as I asked the question I was able to figure it out. Don't know why that happens sometimes.
This code
def f():
# do something here ...
# call f() again in 60 seconds
threading.Timer(60, f).start()
# start calling f now and every 60 sec thereafter
f()
From here: How to execute a function asynchronously every 60 seconds in Python?
Actually works for what I was trying to do. There are evidently some subtleties in how the function is called as an argument in threading.Timer. Before when I was including the arguments and even the parentheses after the function I was getting recursive depth errors --i.e. the function was calling itself without delay constantly.
So anyone else who has a problem like this, pay attention to how you call the function in threading.Timer(60, f).start(). If you write threading.Timer(60, f()).start() or something similar it will probably not work.
I am using this loop for running every 5 minutes just creating thread and it completes.
while True:
now_plus_5 = now + datetime.timedelta(minutes = 5)
while datetime.datetime.now()<= now_plus_5:
new=datetime.datetime.now()
pass
now = new
pass
But when i check my process status it shows 100% usage when the script runs.Does it causing problem?? or any good ways??
Does it causes CPU 100% usage??
You might rather use something like time.sleep
while True:
# do something
time.sleep(5*60) # wait 5 minutes
Based on your comment above, you may find a Timer object from the threading module to better suit your needs:
from threading import Timer
def hello():
print "hello, world"
t = Timer(300.0, hello)
t.start() # after 5 minutes, "hello, world" will be printed
(code snippet modified from docs)
A Timer is a thread subclass, so you can further encapsulate your logic as needed.
This allows the threading subsystem to schedule the execution of your task such that it's not entirely CPU bound like your current implementation.
I should also note that the Timer class is designed to be fired only once. As such, you'd want to design your task to start a new instance upon completion, or create your own Thread subclass with its own smarts.
While researching this, I noticed that there's also a sched module that provides this functionality as well, but rather than rehash the solution, check out this related question:
Python Equivalent of setInterval()?
timedelta takes(seconds,minutes,hours,days,months,years) as input and works accordingly
from datetime import datetime,timedelta
end_time = datetime.now()+timedelta(minutes=5)
while end_time>= datetime.now():
statements
This question already has answers here:
Run certain code every n seconds [duplicate]
(7 answers)
Closed 8 years ago.
I have a threaded class whose loop needs to execute 4 times every second. I know that I can do something like
do_stuff()
time.sleep(0.25)
but the problem is that is doesn't account for the time it takes to do_stuff(). Effectively this needs to be a real-time thread. Is there a way to accomplish this? Ideally the thread would still be put to sleep when not executing code.
The simple solution
import threading
def work ():
threading.Timer(0.25, work).start ()
print "stackoverflow"
work ()
The above will make sure that work is run with an interval of four times per second, the theory behind this is that it will "queue" a call to itself that will be run 0.25 seconds into the future, without hanging around waiting for that to happen.
Because of this it can do it's work (almost) entirely uninterrupted, and we are extremely close to executing the function exactly 4 times per second.
More about threading.Timer can be read by following the below link to the python documentation:
docs.python.org - 16.2.7. Timer Objects
RECOMMENDED] The more advanced/dynamic solution
Even though the previous function works as expected you could create a helper function to aid in dealing with future timed events.
Something as the below will be sufficient for this example, hopefully the code will speak for itself - it is not as advanced as it might appear.
See this as an inspiration when you might implement your own wrapper to fit your exact needs.
import threading
def do_every (interval, worker_func, iterations = 0):
if iterations != 1:
threading.Timer (
interval,
do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1]
).start ()
worker_func ()
def print_hw ():
print "hello world"
def print_so ():
print "stackoverflow"
# call print_so every second, 5 times total
do_every (1, print_so, 5)
# call print_hw two times per second, forever
do_every (0.5, print_hw)
I did a bit different approach with one Thread, looping in a while loop.
For me the advantages are:
Only one Thread, the other solutions mentioned here starting and stopping threads for every interval
More control for the Interval, you are able to stop the IntervalTimer with .stop() method
Code:
from threading import Thread, Event
# StoppableThread is from user Dolphin, from http://stackoverflow.com/questions/5849484/how-to-exit-a-multithreaded-program
class StoppableThread(Thread):
def __init__(self):
Thread.__init__(self)
self.stop_event = Event()
def stop(self):
if self.isAlive() == True:
# set event to signal thread to terminate
self.stop_event.set()
# block calling thread until thread really has terminated
self.join()
class IntervalTimer(StoppableThread):
def __init__(self, interval, worker_func):
super().__init__()
self._interval = interval
self._worker_func = worker_func
def run(self):
while not self.stop_event.is_set():
self._worker_func()
sleep(self._interval)
Usage:
def hw():
print("Hello World")
interval = IntervalTimer(1,hw)
interval.start()
sleep(10)
interval.stop()