Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

" RuntimeError: thread.__init__() not called" when subclassing threading.Thread

I need to run as many threads of class Observer as there are elements in list dirlist. When I run it python console it works all right.

class Observer(Thread):
    def run(self):
        naptime = random.randint(1,10)
        print(self.name + ' starting, running for %ss.' % naptime)
        time.sleep(naptime)
        print(self.name + ' done')

observers = {}
for d in dirlist:
    observers[d] = Observer()
    observers[d].start()

But when I try to do it from a Master thread which is supposed to spawn the Observer threads I get errors.

class Master(Thread):
    def __init__(self, dirlist):
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            observers[d] = Observer()
            observers[d].start()
        while True:
            time.sleep(3600)

master_thread = Master(dirlist)
master_thread.start()

The call to Master.start results in:

RuntimeError: thread.__init__() not called

This looks strange to me.
I am unable to understand whats the difference between both cases.
Can anybody figure out a solution to my problem ?

Somehow following doesn't produce an error, and I don't understand why.

class Master(Thread):
    def set(self, dirlist):
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            observers[d] = Observer()
            observers[d].start()
        while True:
            time.sleep(3600)

master_thread = Master()
master_thread.set(dirlist)
master_thread.start()
like image 457
Nullpoet Avatar asked Sep 16 '11 13:09

Nullpoet


People also ask

Which of the following methods of a thread class can be overridden in Python?

The Thread class represents an activity that is run in a separate thread of control. There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the run() method in a subclass. No other methods (except for the constructor) should be overridden in a subclass.

What is INIT in thread?

__init__() method is called when an object is initialized. And when you do - Thread. __init__(self) , it just just calling the parent class' __init__() method . Like said in comment you can remove it and the functionality should remain same. In your class the __init__() is completely redundant.

Which of the following methods of a thread class can be overridden __ Init__ and run () start () and join () acquire () and Release () sleep () and wait ()?

When extending the Thread class, the child class can override only two methods i.e. the __init__() method and the run() method. No other method can be overridden other than these two methods.


3 Answers

>>> master_thread.start()
RuntimeError: thread.__init__() not called

Make sure to call Thread.__init__() in your Master.__init__:

class Master(Thread):
    def __init__(self, dirlist):
        super(Master, self).__init__()
        self.dirlist = dirlist
like image 118
Ferdinand Beyer Avatar answered Sep 25 '22 23:09

Ferdinand Beyer


Well i know it's late to answer but, what the hell, i am a newbie in python but this same thing was happening to me, so i went back to read the python tutorial and it has some differences with what we both we're trying, hope it helps. instead of this

import threading

class Master(Thread):
    def set(self, dirlist):
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            ...

class according to the python tutorial:

class Master(threading.Thread):

this line is missing:

threading.Thread.__init__(self)

so it will end up being:

import threading

class Master(threading.Thread):
    def __init__(self, dirlist):
        threading.Thread.__init__(self)
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            ...

and that should work, at least work for me. I hope it was helpfull.

And your second try using the set method works, because you are not overriding the

__init__ method

from Thread therefore the original init method from the parent class is used it runs as it's supposed.

like image 28
Drisvalakas Avatar answered Sep 23 '22 23:09

Drisvalakas


Error is clear, you should call thread.__init__():

def __init__(self, dirlist):
    super(Master, self).__init__()
    self.dirlist = dirlist       
like image 27
utdemir Avatar answered Sep 26 '22 23:09

utdemir