I need to print the value of a variable every second or couple of seconds, while "at the same time" this variable is being modified. So I would be modifying this variable in my main function and I want something to print its value every second. Something like:
'''This is my main program'''
for i in range(very large number):
'''do something which modifies the value of 'var' '''
And somewhere else in the code:
'''Every second'''
print var
I took a look at this but I'm not sure if it's what I'm looking for, or how I should use it.
What I need is reaaaly simple, there are no other threads, and I don't care about syncing anything, or when in the main function the value is printed.
You can use threading to print var each second.
try this example:
import threading
var = 5
def printit():
global var
threading.Timer(5.0, printit).start()
print "Hello, World!", var
printit()
import time
for i in range(1000000):
time.sleep(2)
var = i
Basically, the question/answer you pointed to is what you need:
import threading import time
interesting = 0
class MonitorThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global interesting
while(1):
print interesting
time.sleep(1)
MonitorThread().start()
for interesting in range(2000000):
time.sleep(1)
Related
I Have a counting function that I would like to start and restart while getting the live variables to use in another function my problem is while using threading it seams like even global variables don't seem to work to pass variables around. What I want the code to do is have a counter be triggered as needed or maybe free running I'm not sure yet. To be able to reset the counter and get the value of the counter.
Right now the counter will start and run fine but the print_stuff function keeps telling me that there is no attribute countval.
The count thread gets started at startup but I don't necessarily want it to start up immediately, I would like to trigger it as needed but I cant put count_thread.start() twice or it will through a error so I'm calling the thread at startup and then calling the function again to restart it as needed. Maybe there is a more elegant way of doing that.?
import threading
import time
def count():
global countval
for countval in range(3):
print('looping')
time.sleep(1)
def print_stuff():
global countval
e = input("press enter to start")
count()
while True:
if countval == 3:
print("time out")
count_thread = threading.Thread(target=count)
print_thread = threading.Thread(target=print_stuff)
print_thread.start()
count_thread.start()
print_stuff is getting to the if statement before the count function is able to create the variable. Just do them in the opposite order. Either that, or create a global countval = 0 to start things off.
To solve the no attribute problem you can use Queue,
and if you want to stop your counting thread you can set a global variable or you can pass a function (using lambda or inner function or ...) to do that.
Here is one way to do that:
import threading
import time
from queue import Queue
from typing import Callable
def count(q, stop_counting):
# type: (Queue, Callable[[], bool]) -> None
for countval in range(3):
if stop_counting():
print('stopped')
break
print(f'looping {countval}')
q.put(countval)
time.sleep(1)
def print_stuff(q):
# type: (Queue) -> None
while True:
countval = q.get()
print(f'countval gotten: {countval}')
if countval == 3:
print("time out")
def main():
flag_stop_counting = False
q = Queue()
def stop_counting():
return flag_stop_counting
count_thread = threading.Thread(target=count, args=(q, stop_counting,))
print_thread = threading.Thread(target=print_stuff, args=(q,))
print_thread.start()
count_thread.start()
time.sleep(1.25)
flag_stop_counting = True
if __name__ == '__main__':
main()
In this code:
counter checks if it should stop counting or not
counter puts the value that it made to q
print_stuff get the value from q (Note: he waits until counter puts his value in q)
To check that program works:
after 1.25 seconds we change the value of flag_stop_counting
But if you want your counter to only have a for, i guess it's better to don't make it as a thread and run it whenever you want.
Hope it was helpful.
I want to build a function that will stop another function after a set time.
For example:
def start():
global bol_start
bol_start = True
timer()
if bol_start is True:
"do something until time is over"
def stop():
global bol_start
bol_start = False
sys.exit(0)
def timer():
"code for actual timer" ?
I would like to let the user define the time x how long the tool should run start().
After the time is over it should call stop().
If you have a loop in the function, that runs continuously, the simplest mechanic would be to measure time every iteration:
import time
def run():
start = time.time()
stop_seconds = 10
while time.time() - start < stop_seconds:
# do something
If you don't have a loop or the function consists of time consuming operations, you would need to kill the function in the middle of execution like suggested here: Timeout on a function call
I'm using empty while loops a lot, for example:
I have a thread running in the background that will change a value called "a" in 5 seconds. however, I'm using a different function at the same time, and I want to let the second function know that the value has changed, so what I always did was:
import threading, time
class example:
def __init__(self):
self.a = 0
def valchange(self):
time.sleep(5)
self.a += 1
time.sleep(1)
print("im changing the a value to " + str(self.a))
print("those print commands needs to run after notifier stopped his while and started printing")
def notifier(exam :example, num :int):
while(exam.a != num):
pass
print("it changed to " + str(num))
exa = example()
i = 1
while(i <= 16):
temp= threading.Thread(target=notifier, args=(exa, i, ))
temp.start()
i += 3
i = 1
while(i <= 16):
exa.valchange()
i += 1
It's important to mention, that example could not use wait and set to an event, because there is no indication to when you need to run set, and how much threads are running in the background, and even what numbers will have a thread waiting for them to change.
And also you can't use join because changing 'a' is not a sign to print, only the condition is the sign.
Async and select can't help me as well because of the last reason.
Is there any way to create something, that will stop the program fromrunning until the condition will become true? you can provide your solution with any programming language you want, but mainly I'm using python 3.
EDIT: please remember that I need it to work with every condition. And my code example- is only an example, so if something works there, it doesn't necessarily will work with a different condition.
Thank you very much in advance :)
Idea:
wait(a == 5) // will do nothing until a == 5
You need to use select or epoll system calls if you're waiting for some system operation to finish. In case you're waiting for a certain IO event, then you can use asyncio (provided your Python version > 3.3), otherwise you could consider twisted.
If you're doing some CPU bound operations you need to consider multiple processes or threads, only then you can do any such monitoring effectively. Having a while loop running infinitely without any interruption is a disaster waiting to happen.
If your thread only changes a's value once, at the end of its life, then you can use .join() to wait for the thread to terminate.
import threading
import time
class example:
def __init__(self):
self.a = 0
self.temp = threading.Thread(target=self.valchange)
self.temp.start()
self.notifier()
def valchange(self):
time.sleep(5)
self.a = 1
def notifier(self):
self.temp.join()
print("the value of a has changed")
example()
If the thread might change a's value at any point in its lifetime, then you can use one of the threading module's more generalized control flow objects to coordinate execution. For instance, the Event object.
import threading
import time
class example:
def __init__(self):
self.a = 0
self.event = threading.Event()
temp = threading.Thread(target=self.valchange)
temp.start()
self.notifier()
def valchange(self):
time.sleep(5)
self.a = 1
self.event.set()
def notifier(self):
self.event.wait()
print("the value of a has changed")
example()
One drawback to this Event approach is that the thread target has to explicitly call set() whenever it changes the value of a, which can be irritating if you change a several times in your code. You could automate this away using a property:
import threading
import time
class example(object):
def __init__(self):
self._a = 0
self._a_event = threading.Event()
temp = threading.Thread(target=self.valchange)
temp.start()
self.notifier()
#property
def a(self):
return self._a
#a.setter
def a(self, value):
self._a = value
self._a_event.set()
def valchange(self):
time.sleep(5)
self.a = 1
def notifier(self):
self._a_event.wait()
print("the value of a has changed")
example()
Now valchange doesn't have to do anything special after setting a's value.
What you are describing is a spin lock, and might be fine, depending on your use case.
The alternative approach is to have the code you are waiting on call you back when it reaches a certain condition. This would require an async framework such as https://docs.python.org/3/library/asyncio-task.html
There are some nice simple examples in those docs so I won't insult your intelligence by pasting them here.
I am working on my code to set up the timer. I want to set up the Timer without creating the function.
Here is what I use:
def hello(self):
print "hello, world"
self.getControl(MyPlayer.Control_EPG_ID).setVisible(False)
def onAction(self, action):
if action.getId() == ACTION_MOVE_DOWN:
t = threading.Timer(5.0, self.hello)
t.start()
I want to make it to show something is like this:
t = threading.Timer(5.0)
t.start()
self.getControl(MyPlayer.Control_EPG_ID).setVisible(False)
when I try it, it give me an error. Do you know how I can set up the timer without create a function? if so how?
You should be able to nest hello() inside of onAction() like this. It will use the self argument passed to the outer function:
def onAction(self, action):
def hello():
print "hello, world"
self.getControl(MyPlayer.Control_EPG_ID).setVisible(False)
if action.getId() == ACTION_MOVE_DOWN:
t = threading.Timer(5.0, hello)
t.start()
Why not like this:
import time
time.sleep(5) # delays for 5 seconds
I have a question regarding the example posted below...
On my machine calcIt() function takes about 5 seconds to complete.
The same calcIt() function is called from inside of MyClass's callCalcIt() method.
Using while loop MyClass is "watching" for calcIt() function to finish.
Question: A while loop inside of calcIt() method prints out '...running' only once. Honestly I was expecting to see at least 'an infinite loop' type of behavior where '...running' would be printed thousand times per second. Observing a fact the while loop executes a print '...running' line only once makes me believe while loop watches very 'loosely' for calcIt()'s progress. If so, what other (other than while loop) approach should be used to make sure you get what you want: an instant feedback from calcIt() function?
def calcIt():
a=True
while a:
for i in range(25000000):
pass
a=False
return True
class MyClass(object):
def __init__(self):
super(MyClass, self).__init__()
def callCalcIt(self):
b=True
while b:
result=calcIt()
print '...running'
if result: b=False
print 0
calcIt()
print 1
c=MyClass()
c.callCalcIt()
print 2
EDITED LATER:
Posting a revised code with an implementation of solution suggested by Ebarr:
import threading
updateMe=[]
def calcIt():
a=True
while a:
for y in range(3):
for i in range(15000000):
pass
updateMe.append(1)
a=False
return True
class MyClass(object):
def __init__(self):
super(MyClass, self).__init__()
def callCalcIt(self):
thread = threading.Thread(target=calcIt)
thread.start()
print '\n...thread started'
while thread.is_alive():
if len(updateMe)==1: print '...stage 1'
if len(updateMe)==2: print '...stage 2'
if len(updateMe)==3: print '...stage 3'
def printUpdate(self):
print 'updateMe=', len(updateMe)
c=MyClass()
c.callCalcIt()
I'm not sure what you were expecting to happen, but the explanation is very simple. You are running a single threaded code. This means that all of the above will be executed in serial, so there will be no concurrency between the two while loops in your code.
What you appear to be asking is how to thread your code such that you can check the progress of a running function. If that is the case, you can turn calcIt into a thread.
import threading
class CalcIt(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
for i in range(25000000):
pass
You would then change callCalcIt to:
def callCalcIt(self):
thread = CalcIt()
thread.start()
while thread.is_alive():
print '...running'
Alternatively, you can make it simpler:
import threading
def calcIt():
for i in range(25000000):
pass
def callCalcIt():
thread = threading.Thread(target=calcIt)
thread.start()
while thread.is_alive():
print '...running'
callCalcIt()
I can come up with two ways of doing that, but both require some modification to the calcIt function.
Method 1, callbacks:
def calc_it(callback):
r = 25000000
for x in xrange(r+1):
if not (x % 1000):
callback(x, r) # report every 1000 ticks
class Monitor(object):
def print_status(self, x, r):
print "Done {0} out of {1}".format(x, r)
def call(self):
calc_it(self.print_status)
Method 2, generator:
def calc_it():
r = 25000000
for x in xrange(r+1):
if not (x % 1000): # report every 1000 ticks
yield x, r
class Monitor(object):
def call(self):
for x, r in calc_it():
print "Done {0} out of {1}".format(x, r)
(A side note: in neither case Monitor has to be a class, that's just for consistency with the original code.)
Not sure exactly what you are trying to accomplish, but you could possibly use my newly written generator state machine thingie. Like so:
from generatorstate import State
def calcIt():
while True:
for i in range(25000000):
pass
yield
tick = State(calcIt)
print 0
tick()
print 1
tick()
print 2
I've added a couple of examples, sneak a peek at those if you think it might be a fit.