Reputation: 2611
I am building a monitoring system where I once start the application, it will continuously monitor the changes and output the results to the database. For this, I used a while loop for continuous monitoring for the repetitive tasks. Here, I am using a class-level variable as 'True' for the condition in while loop. Here I am stuck with how can I change the flag to 'False' when the application is running in while loop.
Sample code looks as follow:
class Monitor:
def __init__(self):
self.monitor=True
def start(self):
i=0
while(self.monitor):
i+=1
I am running the below lines to run the code in the command line:
>>> from StartStopMontoring import Monitor
>>> m=Monitor()
>>> m.start()
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Volumes/DATA/Innominds/WorkSpace/Python/StartStopMontoring.py", line 7, in start
while(self.monitor):
KeyboardInterrupt
>>>
Second-line creates the object and the third line calls the function, then I am unable to set the flag to false since it is in while loop with always true condition is met. (I had to interrupt the command line to stop the application).
Precisely, How can I set a class level flag to false when while loop is running?
Note: This flag changes happen from external input like user want to stop the system but not when conditions met internally within the loop.
Upvotes: 1
Views: 131
Reputation: 3296
With below code you can either temporarily halt the monitoring, or quit the monitoring completely.
import threading
import time
class Monitor(threading.Thread):
def __init__(self):
self.b_quit = False
self.monitor = True
self.event = threading.Event() # Whenever this event is set, monitoring should happen
self.event.set() # By default turn on monitoring
threading.Thread.__init__(self)
def run(self):
i = 0
while self.monitor:
eventSet = self.event.wait()
if not self.monitor or self.b_quit:
break
print("---- Thread is active: {}".format(i), end='\r')
i += 1
def begin(self):
self.event.set()
def halt(self):
self.event.clear()
def quit(self):
self.event.set()
self.b_quit = True
obj = Monitor()
obj.start() # Launches a separate thread which can be controlled, based upon calls to begin, halt, and quit
time.sleep(1)
print("Trigger halt from main thread")
obj.halt() # Only paused the monitoring
time.sleep(1)
print("Trigger resume from main thread")
obj.begin() # Resumes the monitoring
time.sleep(1)
print("Trigger quit from main thread")
obj.quit() # Exits the thread completely
Upvotes: 1
Reputation: 189
Launch the loop in a different thread so that you don't lose the control of your program.
import threading
class Monitor:
(....)
def start(self):
threading.Thread(target=self.run).start()
def run(self):
i=0
while self.monitor:
i += 1
Upvotes: 1