Python - How can I implement a 'stoppable' thread?

前端 未结 3 1481
梦毁少年i
梦毁少年i 2020-12-21 07:21

There is a solution posted here to create a stoppable thread. However, I am having some problems understanding how to implement this solution.

Using the code...

相关标签:
3条回答
  • 2020-12-21 08:00

    There are a couple of problems with how you are using the code in your original example. First of all, you are not passing any constructor arguments to the base constructor. This is a problem because, as you can see in the plain-Thread example, constructor arguments are often necessary. You should rewrite StoppableThread.__init__ as follows:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._stop_event = threading.Event()
    

    Since you are using Python 3, you do not need to provide arguments to super. Now you can do

    testthread = StoppableThread(target=funct)
    

    This is still not an optimal solution, because funct uses an external variable, testthread to stop itself. While this is OK-ish for a tiny example like yours, using global variables like that normally causes a huge maintenance burden and you don't want to do it. A much better solution would be to extend the generic StoppableThread class for your particular task, so you can access self properly:

    class MyTask(StoppableThread):
        def run(self):
            while not self.stopped():
                time.sleep(1)
                print("Hello")
    
    testthread = MyTask()
    testthread.start()
    time.sleep(5)
    testthread.stop()
    

    If you absolutely do not want to extend StoppableThread, you can use the current_thread function in your task in preference to reading a global variable:

    def funct():
        while not current_thread().stopped():
            time.sleep(1)
            print("Hello")
    
    testthread = StoppableThread(target=funct)
    testthread.start()
    sleep(5)
    testthread.stop()
    
    0 讨论(0)
  • 2020-12-21 08:03

    I found some implementation of a stoppable thread - and it does not rely that You check if it should continue to run inside the thread - it "injects" an exception into the wrapped function - that will work as long as You dont do something like :

    while True: 
        try: 
            do something
        except:
            pass
    

    definitely worth looking at !

    see : https://github.com/kata198/func_timeout

    maybe I will extend my wrapt_timeout_decorator with such kind of mechanism, which You can find here : https://github.com/bitranox/wrapt_timeout_decorator

    0 讨论(0)
  • 2020-12-21 08:22

    Inspired by above solution I created a small library, ants, for this problem.

    Example

    from ants import worker
    
    @worker
    def do_stuff():
        ...
        thread code
        ...
    
    do_stuff.start()
    ...
    do_stuff.stop()
    

    In above example do_stuff will run in a separate thread being called in a while 1: loop

    You can also have triggering events , e.g. in above replace do_stuff.start() with do_stuff.start(lambda: time.sleep(5)) and you will have it trigger every 5:th second

    The library is very new and work is ongoing on GitHub https://github.com/fa1k3n/ants.git

    0 讨论(0)
提交回复
热议问题