(python) execute function every x seconds - python

this is my source code that executes function every 1 seconds
buy, it only executes one times.
In short, I want to get the # of line from the named pipe output every seconds
Is there any suggestion for this problem?
thank you for your help in advance
class Monitor:
def __init__(self, namedpipe, name):
self.namedpipe = namedpipe
self.name = name
self.count = 0
def run(self):
print self.name+" start run"
while True:
line = self.namedpipe.readline()
self.count = self.count+1
def getCost(self):
print "Hi"
while True:
line = monitor.readline()
line = line.strip()
if not line:
ans =raw_input('stop?')
if ans=='y': break
monitorList = open(line, 'r')
m = Monitor(monitorList, line)
thread.start_new_thread(m.run, ())
time.sleep(1)
threading.Timer(0.1, m.getCost).start()

With Threading.Timer, you have to restart the timer each time it has expired - so during the execution of the function called when the timer expires - m.getCost in your code - the timer has to be started again. You might want to define a wrapper function to do this work, to avoid polluting m.getCost() with timer stuff.

Related

How can I run a function forever?

Im trying to run the listener function forever, for example I want any time there is new information available in the stream it updates on the list automatically. Any idea in how to do it would be appreciated.
class Notifications(Screen):
notificationslist = ObjectProperty(None)
def listener(self, event = None):
notifications_screen = self.manager.get_screen('notif')
print(event.event_type) # can be 'put' or 'patch'
print(event.path) # relative to the reference, it seems
print(event.data) # new data at /reference/event.path. None if deleted
notifications = event.data
if notifications.items() == None:
return
else:
for key, value in notifications.items():
thevalue = value
notifications_screen.notificationslist.adapter.data.extend([value[0:17] + '\n' + value[18:]])
print(thevalue)
id = (thevalue[thevalue.index("(") + 1:thevalue.rindex(")")])
print(id)
If you want a function to run forever but that does not block you from doing other functions, then you can use threads.
Here is an example with example_of_process that runs forever, and then the main program with time.sleep(3)
import threading
import time
def example_of_process():
count = 0
while True:
print("count", count)
count += 1
time.sleep(1)
thread_1 = threading.Thread(target=example_of_process)
thread_1.daemon = True # without the daemon parameter, the function in parallel will continue even if your main program ends
thread_1.start()
# Now you can do anything else. I made a time sleep of 3s, otherwise the program ends instantly
time.sleep(3)

How can I implement this where I print this message every __ seconds __ times?

I want to call the printFunction method every __ seconds, but I want to stop the scheduling after a certain number of calls. Say for example, print every 5 seconds 10 times. Pulling those frequency and run time values in from another file.
Running in PyCharm.
import schedule
import time
class example:
# basic function to print
def printFunction(self):
print("Hello world")
def repeated(self):
# reads in two values from another file
systemFrequency = float(freqSettings.systemFrequency)
systemRunTime = int(freqSettings.systemRunTime)
global count
count = 0
while (count < systemRunTime):
self.printFunction
self.increaseCount
def increaseCount(self):
global count
count += 1
The function run by the scheduler need to return CancelJob to stop being scheduled.
Here is how i've implemented it :
import schedule
def my_function():
print("hello world")
def wrapper():
wrapper.counter +=1
my_function()
if wrapper.counter == 10:
return schedule.CancelJob
wrapper.counter = 0
schedule.every(1).seconds.do(wrapper)
while True:
schedule.run_pending()
print(schedule)
It displays 10 "hello world"

Sharing Time variable Between two threads

Hi i need to create 2 threads one which repeatedly writes the time of day as an
HH:MM:SS string into a global variable 100 times per second. The second thread will repeatedly read the time of day
string from that variable twice per second and try to display it to screen but code in that thread should ensure the same
string is never written twice in a row. The result is that second thread really displays to screen only once per second. i have tried following code but its not working
import threading
import time
c = threading.Condition()
flag = 0 #shared between Thread_A and Thread_B
val = ''
class Thread_A(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run(self):
global flag
global val #made global here
while True:
c.acquire()
if flag == 0:
time.sleep(0)
flag = 1
a=range(1,101)
for i in a:
val=time.strftime("%H:%M:%S", time.localtime(time.time()))
c.notify_all()
else:
c.wait()
c.release()
class Thread_B(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run(self):
global flag
global val #made global here
while True:
c.acquire()
if flag == 1:
#time.sleep(1)
flag = 0
a=range(0,2)
for i in a:
print str(val)
#val = 20
c.notify_all()
else:
c.wait()
c.release()
a = Thread_A("myThread_name_A")
b = Thread_B("myThread_name_B")
b.start()
a.start()
a.join()
b.join()
You're making this more complicated than it needs to be. You can use a simple Lock object to make sure that only one thread can access val at a time.
The code below will run on Python 2 or Python 3. To stop it, hit Enter
import time
from threading import Thread, Lock
# Rename Python 2's raw_input to input
try:
input = raw_input
except NameError:
pass
val = ''
lock = Lock()
def set_time(delay=0.01):
''' Write the current time to val '''
global val
while True:
lock.acquire()
val = time.strftime("%H:%M:%S")
lock.release()
time.sleep(delay)
def get_time(delay=0.5):
''' Read the current time from val and print
it if it hasn't been printed already
'''
oldval = ''
while True:
lock.acquire()
if val != oldval:
print(val)
oldval = val
lock.release()
time.sleep(delay)
# Start the threads
for func in (set_time, get_time):
t = Thread(target=func)
t.setDaemon(True)
t.start()
#Wait until we get some input
s = input()
some typical output
02:22:04
02:22:05
02:22:06
02:22:07
02:22:08

Is it possible to execute function every x seconds in python, when it is performing pool.map?

I am running pool.map on big data array and i want to print report in console every minute.
Is it possible? As i understand, python is synchronous language, it can't do this like nodejs.
Perhaps it can be done by threading.. or how?
finished = 0
def make_job():
sleep(1)
global finished
finished += 1
# I want to call this function every minute
def display_status():
print 'finished: ' + finished
def main():
data = [...]
pool = ThreadPool(45)
results = pool.map(make_job, data)
pool.close()
pool.join()
You can use a permanent threaded timer, like those from this question: Python threading.timer - repeat function every 'n' seconds
from threading import Timer,Event
class perpetualTimer(object):
# give it a cycle time (t) and a callback (hFunction)
def __init__(self,t,hFunction):
self.t=t
self.stop = Event()
self.hFunction = hFunction
self.thread = Timer(self.t,self.handle_function)
def handle_function(self):
self.hFunction()
self.thread = Timer(self.t,self.handle_function)
if not self.stop.is_set():
self.thread.start()
def start(self):
self.stop.clear()
self.thread.start()
def cancel(self):
self.stop.set()
self.thread.cancel()
Basically this is just a wrapper for a Timer object that creates a new Timer object every time your desired function is called. Don't expect millisecond accuracy (or even close) from this, but for your purposes it should be ideal.
Using this your example would become:
finished = 0
def make_job():
sleep(1)
global finished
finished += 1
def display_status():
print 'finished: ' + finished
def main():
data = [...]
pool = ThreadPool(45)
# set up the monitor to make run the function every minute
monitor = PerpetualTimer(60,display_status)
monitor.start()
results = pool.map(make_job, data)
pool.close()
pool.join()
monitor.cancel()
EDIT:
A cleaner solution may be (thanks to comments below):
from threading import Event,Thread
class RepeatTimer(Thread):
def __init__(self, t, callback, event):
Thread.__init__(self)
self.stop = event
self.wait_time = t
self.callback = callback
self.daemon = True
def run(self):
while not self.stop.wait(self.wait_time):
self.callback()
Then in your code:
def main():
data = [...]
pool = ThreadPool(45)
stop_flag = Event()
RepeatTimer(60,display_status,stop_flag).start()
results = pool.map(make_job, data)
pool.close()
pool.join()
stop_flag.set()
One way to do this, is to use main thread as the monitoring one. Something like below should work:
def main():
data = [...]
results = []
step = 0
pool = ThreadPool(16)
pool.map_async(make_job, data, callback=results.extend)
pool.close()
while True:
if results:
break
step += 1
sleep(1)
if step % 60 == 0:
print "status update" + ...
I've used .map() instead of .map_async() as the former is synchronous one. Also you probably will need to replace results.extend with something more efficient. And finally, due to GIL, speed improvement may be much smaller than expected.
BTW, it is little bit funny that you wrote that Python is synchronous in a question that asks about ThreadPool ;).
Consider using the time module. The time.time() function returns the current UNIX time.
For example, calling time.time() right now returns 1410384038.967499. One second later, it will return 1410384039.967499.
The way I would do this would be to use a while loop in the place of results = pool(...), and on every iteration to run a check like this:
last_time = time.time()
while (...):
new_time = time.time()
if new_time > last_time+60:
print "status update" + ...
last_time = new_time
(your computation here)
So that will check if (at least) a minute has elapsed since your last status update. It should print a status update approximately every sixty seconds.
Sorry that this is an incomplete answer, but I hope this helps or gives you some useful ideas.

Implementing Timeout. Whats wrong with the following code?

The program prints Expired the first time. I am expecting the code to print "not expired" for atleast 4 times before printing expired. Can someone please explain the reason and help me correct the code. Thank you
import time
TIMEOUT = 5
class Timer ():
def __init__(self):
self.timeout = time.time()+TIMEOUT
def isExpired ():
return time.time() > self.timeout
timing = Timer()
def main():
while 1:
if timing.isExpired:
print "Expired"
return
else:
print "Not expired"
print "sleeping for 1 second"
time.sleep(1)
if __name__== "__main__":
main()
You have several problems:
You did not give your isExpired method a self argument. Define it as def isExpired(self):.
You are creating a new Timer instance on each loop iteration. Move the timing = Timer() outside the while loop.
timing.isExpired is a reference to the method object iself (which is always true in a boolean context). You need to do timing.isExpired() to actually call it.
These are all basic Python issues that have nothing to do with Timer. Read the Python tutorial to learn how to use classes and so on.
You are creating a Timer instance everytime. Take it away from loop, or your while loop is never going to terminate. Also, you need to call timing.isExpired as it is a method. So your code should be:
import time
TIMEOUT = 60 * 5
class Timer ():
def __init__(self):
self.timeout = time.time()+TIMEOUT
def isExpired (self):
return time.time() > self.timeout
def main():
timing = Timer()
while 1:
if timing.isExpired():
print "Expired"
return
else:
print "Not expired"
print "sleeping for 1 second"
time.sleep(1)

Categories

Resources