8

I spent the last hour(s???) looking/googling for a way to have a class start one of its methods in a new thread as soon as it is instanciated.

I could run something like this:

x = myClass()

def updater():
    while True:
        x.update()
        sleep(0.01)

update_thread = Thread(target=updater) 
update_thread.daemon = True
update_thread.start()

A more elegant way would be to have the class doing it in init when it is instanciated. Imagine having 10 instances of that class... Until now I couldn't find a (working) solution for this problem... The actual class is a timer and the method is an update method that updates all the counter's variables. As this class also has to run functions at a given time it is important that the time updates won't be blocked by the main thread.

Any help is much appreciated. Thx in advance...

1
  • 1
    What problem did you encounter when you tried to put that code in MyClas.__init__? Commented Aug 24, 2013 at 7:50

2 Answers 2

22

You can subclass directly from Thread in this specific case

from threading import Thread

class MyClass(Thread):
    def __init__(self, other, arguments, here):
        super(MyClass, self).__init__()
        self.daemon = True
        self.cancelled = False
        # do other initialization here

    def run(self):
        """Overloaded Thread.run, runs the update 
        method once per every 10 milliseconds."""

        while not self.cancelled:
            self.update()
            sleep(0.01)

    def cancel(self):
        """End this timer thread"""
        self.cancelled = True

    def update(self):
        """Update the counters"""
        pass

my_class_instance = MyClass()

# explicit start is better than implicit start in constructor
my_class_instance.start()

# you can kill the thread with
my_class_instance.cancel()
Sign up to request clarification or add additional context in comments.

2 Comments

Beat me by half a minute. +1 for good answer. You should probably include at least the signature for the update method, since your answer looks like it's supposed to be a complete working piece of code. Also, it misses an import statement for sleep.
This works like a charm... Sometimes the solution is extremely simple. I had a similar approach but I couldn't get it running. Thanks so much... Sometimes I just can't see the wood for the trees.
2

In order to run a function (or memberfunction) in a thread, use this:

th = Thread(target=some_func)
th.daemon = True
th.start()

Comparing this with deriving from Thread, it has the advantage that you don't export all of Thread's public functions as own public functions. Actually, you don't even need to write a class to use this code, self.function or global_function are both equally usable as target here.

I'd also consider using a context manager to start/stop the thread, otherwise the thread might stay alive longer than necessary, leading to resource leaks and errors on shutdown. Since you're putting this into a class, start the thread in __enter__ and join with it in __exit__.

Comments

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.