Reputation: 874
I am wondering if I can run a while
loop inside a method of a Python class that can be stopped from another method.
For example, something like this:
from time import sleep
class example():
global recording
def __init__(self):
pass
def start(self):
global recording
recording = True
while recording:
print(1)
def stop(self):
global recording
recording = False
print("SLEEEPINGGGGGGGGGGG")
a = example()
a.start()
sleep(0.5)
a.stop()
But, it does not work, the loop does not stop.
EDIT Since I do not want to create a Thread outside the class, I just tried this, but it doesn't work either.
from time import sleep
import threading
class example():
def __init__(self):
self.is_running = False
def start(self):
self.is_running = True
self.loop_thread = threading.Thread(target=self.main_loop)
def main_loop(self):
while self.is_running:
sleep(0.5)
print(1)
def stop(self):
self.is_running = False
print("SLEEEPINGGGGGGGGGGG")
a = example()
a.start()
sleep(3)
a.stop()
Upvotes: 4
Views: 1351
Reputation: 1327
You have to start your thread after initiating it:
from time import sleep
import threading
class example():
def __init__(self):
self.is_running = False
def start(self):
self.is_running = True
self.loop_thread = threading.Thread(target=self.main_loop)
self.loop_thread.start() # <--- you forgot to start your thread
def main_loop(self):
while self.is_running:
sleep(0.5)
print(1)
def stop(self):
self.is_running = False
print("SLEEEPINGGGGGGGGGGG")
a = example()
a.start()
sleep(3)
a.stop()
Upvotes: 1
Reputation: 140276
a.start()
is an infinite loop. Since nothing runs at the same time, it just runs and never reaches the next statements.
You need to create a thread, like this
import time,threading
class example():
def __init__(self):
self.__recording = False
def start(self):
self.__recording = True
while self.__recording:
time.sleep(1)
print(1)
def stop(self):
self.__recording = False
a = example()
t = threading.Thread(target=a.start)
t.start()
time.sleep(5)
a.stop()
t.join()
note that I have used a member variable instead of a global. When the start
method sees that the variable is True
, it quits the loop. job done.
That works because I'm using sleep()
. If you're running a pure python CPU intensive job that won't work because of python GIL
As suggested in comments, you can go one step further and inherit from threading.Thread
method instead:
import time,threading
class example(threading.Thread):
def __init__(self):
threading.Thread.__init__(self,target=self.run)
self.__recording = False
def run(self):
self.__recording = True
while self.__recording:
time.sleep(1)
print(1)
def join(self):
self.__recording = False
threading.Thread.join(self)
a = example()
a.start()
time.sleep(5)
a.join()
Note that stop
method is now replaced by join
which signals the recording thread to stop then calls the parent join
method. So when you join
you stop the loop automatically first.
Upvotes: 7