1

I want to create a thread class in python3. I want to control an infinite loop in one of the class function. I want to start or stop this loop in my main function outside the class. suppose this code:

import threading
from time import sleep
class my_thread(threading.Thread):
    """Thread class with a stop() method. The thread itself has to check
    regularly for the stopped() condition."""

    def __init__(self):
        super(my_thread, self).__init__()
        self._stop_event = threading.Event()

    def stop(self):
        print("stopping the thread")
        self._stop_event.set()

    def stopped(self):
        return(self._stop_event.is_set())

    def run(self):
        print("running the thread")
        print("start function startt()")
        self._stop_event.clear()
        self.startt()

    def startt(self):
        print("it is going to wait forever")
        while not self.stopped():
            #wait forever, this part is going to run again and again
            pass
        print("This line never executes")


if __name__+'__main__':
    thr=my_thread()
    thr.start()
    sleep(5)
    print("stopping the thread")
    thr.stop()
    # I cant start the thread and relative while loop again
    #thr.start()   
    print("Exiting the whole program")

But the problem is I can't start the thread twice, so what I want is to have two function for start and stop my while loop. I dont need to stop the thread but I need to control it. It means I want to call stop() and startt() functions for many times whenever needed in my main routine. Thanks

2
  • 1
    You can use a Queue to pass a command to a thread. - stackoverflow.com/questions/25904537/… Commented Aug 10, 2017 at 9:35
  • @droravr thanks for the tip but I'm thinking to use of event because it is simpler, how to use Queue for controlling a loop inside the thread? Commented Aug 10, 2017 at 9:40

1 Answer 1

1

first, use Queue in my_thread class for manage task( method ) that complete or called by your thread

you can use LIFO Queue , Prioritry Queue ,FIFO Queue detail

second, add a class-method so you can add new method or task into the queue

add below code into your code :

from queue import Queue
# or
# from multiprocessing import Queue
class my_thread(threading.Thread):
    queue = Queue()

    @classmethod
    def add_task(cls,callable_task):
        cls.queue.put(callable_task)

    def startt(self):
        print("it is going to wait forever")
        while not self.stopped():
            #wait forever, this part is going to run again and again
            if not  self.queue.empty():
                  _m = self.queue.get()
                 # do what ever you want to do with _m

        print("This line never executes")

for stop thread

 Class my_thread(Threading.Thread)
     stop_event = threading.Event()

     @classmethod
     def stop_thread(cls)
         cls.stop_event.set()

     def startt(self):
         print("it is going to wait forever")
         cls = self.__class__
         while not cls.stop_event.is_set():
             #wait forever, this part is going to run again and again
             if not  self.queue.empty():
                 _m = self.queue.get()
                 # do what ever you want to do with _m

         print("This line never executes")

Now call for stop therad

  my_thread.stop_thread()

Exapmle

import threading
import time
class my_thread(threading.Thread):
    stop_event = threading.Event()

    @classmethod
    def stop_thread(cls):
        cls.stop_event.set()

    def run(self):
        print("running the thread")
        print("start function startt()")
        self.__class__.stop_event.clear()
        self.startt()

    def startt(self):
        print("it is going to wait forever")
        cls = self.__class__
        print cls.stop_event.is_set()
        while not cls.stop_event.is_set():
            pass

        print("This line never executes")

a = my_thread()
a.start()
time.sleep(0.5)
my_thread.stop_thread()
print "\n\n\n"
b = my_thread()
b.start()
time.sleep(0.5)
my_thread.stop_thread()
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the answer. I tried your code but how can I start and stop the loop outside the class (in my main) and what is _m?
@MasoudR. I update my answer please check and add above code into your code and _m is object that add into queue
I used both codes, but I get the same result as mine, in my example the stop method works fine but I can't start it again, if I call startt() function after calling stop() It stuck on the loop and can't call stop() function again.
I can't use it because startt() function never ends, it has an infinite loop inside or maybe I'm using it in a wrong way. Can you please edit my code and put all codes to gather?
@MasoudR. you have to add time delay in the start and stop of thread and run above example with time delay and without time delay and check your printed output
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.