Shades88
Shades88

Reputation: 8360

thread not exiting python

I wrote a small threading example in python. I am facing problem that when there's an exception inside a thread, that thread keeps on running and it won't exit. I have following code:

class Producer (threading.Thread):

    def __init__(self, threadId):
        threading.Thread.__init__(self)
        self.threadId  = threadId
        self.killReceived = False

    def produce(self):
        while 1:
            if self.killReceived == True:
                print self.threadId+"inside kill section"
                return False
            print "running"
            time.sleep(1) 
            raise Exception('boo')

    def run(self):
        try:
            self.produce()
        except Exception as e:
            ThreadManager.getInstance().shutdown(self.threadId)

    def stop(self):
        self.killReceived = True

class ThreadManager:
    _instance = None

    @staticmethod
    def getInstance():
        if ThreadManager._instance == None:
            ThreadManager._instance = ThreadManager()
        return ThreadManager._instance

    def __init__(self):
        ''' some initializations '''

    def shutdown(self, threadId):
        while threading.active_count() > 1:
            for thread in threading.enumerate():    
                if type(thread) != threading._MainThread: #never kill main thread directly
                    thread.stop()
                    #print thread.threadId+" is alive? "+str(thread.isAlive())

When I raise exception inside producer it gets caught and I fire shutdown method of ThreadManager, which in turn calls stop() method of all running threads except main thread. Consumer exits using this strategy but producer hangs. If I run isAlive method I see that producer threads are still running, however it's run method is no longer running. Because it no longer print running.As exception bubbles out of produce method which is inside run(), so thread should automatically finish. But it doesn't. So where exactly is the producer? How can I make it stop when some exception occurs?

Upvotes: 1

Views: 2730

Answers (1)

phihag
phihag

Reputation: 287835

ThreadManager's shutdown is not properly synchronized; it basically is a while threading.active_count() > 1 loop that is never exited. If two or more threads end up in this method, they (and the program) will never exit.

Instead of continually calling random threads (which may not even be related to yours), simply keep an inventory of all started threads in ThreadManager, and call stop of each of them once. Also, the code that actually calls stop should move into the ThreadManager, where it logically belongs.

Additionally, ThreadManager.getInstance is not thread-safe; you may end up with multiple ThreadManagers as it stands. You should use a lock.

All in all, it looks like you're reimplementing a ThreadPoolExecutor. Why don't you use that instead?

Upvotes: 2

Related Questions