Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Breaking a while loop from other method inside the same class in Python

Tags:

python

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()
like image 667
Víctor Martínez Avatar asked Oct 30 '25 05:10

Víctor Martínez


2 Answers

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.

like image 93
Jean-François Fabre Avatar answered Oct 31 '25 18:10

Jean-François Fabre


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()
like image 43
jusx Avatar answered Oct 31 '25 19:10

jusx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!