Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Python3.6

Python: Reusable Thread Class

5.00/5 (3 votes)
14 Dec 2018CPOL 12.8K  
This article provides code for making a Thread reusable.

Introduction

Creating a lot of threads gets expensive over time. If it's just necessary to change some input values and then run the thread again, it's faster to reuse a previously created thread. Unfortunately, Python does not support such behaviour.

Here is a class that can rerun a threaded function as often as you want.

Using the Code

The Class Itself

For details, see the comments:

Python
from threading import Thread, Event

class ReusableThread(Thread):
    """
    This class provides code for a restartale / reusable thread

    join() will only wait for one (target)functioncall to finish
    finish() will finish the whole thread (after that, it's not restartable anymore)
        
    """

    def __init__(self, target, args):
        self._startSignal = Event()
        self._oneRunFinished = Event()
        self._finishIndicator = False
        self._callable = target
        self._callableArgs = args

        Thread.__init__(self)

    def restart(self):
        """make sure to always call join() before restarting"""
        self._startSignal.set()

    def run(self):
        """ This class will reprocess the object "processObject" forever.
        Through the change of data inside processObject and start signals
        we can reuse the thread's resources"""

        self.restart()
        while(True):    
            # wait until we should process
            self._startSignal.wait()

            self._startSignal.clear()

            if(self._finishIndicator):# check, if we want to stop
                self._oneRunFinished.set()
                return
            
            # call the threaded function
            self._callable(*self._callableArgs)

            # notify about the run's end
            self._oneRunFinished.set()

    def join(self):
        """ This join will only wait for one single run (target functioncall) to be finished"""
        self._oneRunFinished.wait()
        self._oneRunFinished.clear()

    def finish(self):
        self._finishIndicator = True
        self.restart()
        self.join()

Example of Using the Code

Python
def doSomething(objectToProcess):
    print(str(objectToProcess[0]))
    pass

changableObject = [0]
thread = ReusableThread(target = doSomething, 
         args = [changableObject]) #we need [] to tell python it's a list

# start the thread
changableObject[0] = 1
thread.start()

thread.join()

changableObject[0] = 2
thread.restart()

thread.join()

changableObject[0] = 3
thread.restart()

thread.join()

thread.finish()

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)