views:

139

answers:

5

I have some threads fishing into a queue for jobs, something like this:

class Worker(Thread):
    [...]
    def run(self):
        while not self.terminated:
            job = myQueue.get_nowait()
            job.dosomething()
            sleep(0.5)

Now, self.terminated is just a bool value I use to exit the loop but, this is the problem, several times in a day they stop working without my intervention. All of them but one: the application starts with, lets say, 5 working threads and at random time I check them and one only is working. All the others have both Thread_initialized and Thread_stopped fields true. Threads and jobs does not interact with each other. What I should look for?

PS: I understand it's really hard to try to figure out the issue without the actual code, but it's huge.

UPDATE: actually Queue.Empty is the only exception trapped - guess I believed to let all the jobs' internal errors to propagate without kill the threads eheh - so I'm going to block all the exceptions and see...

+1  A: 

stackoverflow? :)

Shrike
Closed as not a real answer. This answer is humorous, entertaining, or doesn't take itself seriously enough.
Spencer Nelson
Absolutly, but a stack overflow is very likely reason to a thread to die. But the whole behavior of a app depends on the platform indeed, I don't know how Python treats background treads termination.
Shrike
+2  A: 

As example, an exception inside the loop will stop the thread.

Why do you use get_nowait() and not get()? What if the Queue is empty?

leoluk
He doesn't use a poison pill to signify that the threads should die - instead he and sets the "terminated" flag as a loop exit condition which requires non-blocking gets to evaluate
Jeremy Brown
Oof, let me back up. Your point was probably to use the optional timeout of a blocking get. +1!
Jeremy Brown
it was a cuncurrency issue, two threads trying to write in the same file, I was stupid to not expecting errors from inside the jobs :P btw thank you and all the others for the answers.
Giorgio Gelardi
A: 

GIL? at one time only an interpreter is doing the job if you want true parallelization you must use multiprocessing see http://docs.python.org/library/multiprocessing.html

Xavier Combelle
I don't need a true parallelization, anyway I think the GIL reason to be is to let the threads to works, not to kill them
Giorgio Gelardi
Does Thread_stopped means the thread is terminated or does it means it is halted because of any reason and will go back?
Xavier Combelle
+3  A: 

If that is the actual code it's pretty obvious: myQueue.get_nowait() raises an Exception (Empty) when the queue is empty!

THC4k
+1  A: 

I have two suggestions.

1) get_nowait() will raise a Queue.Empty exception if no items are available. Make sure exceptions aren't killing your threads.

2) Use get() instead. Put a None in your queue to signal the thread to exit instead of the boolean flag. Then you don't need a half second sleep and you'll process items faster.

def run(self):
    while True:
        job = queue.get()
        if job:
            try:
                job.do_something()
            except Exception as e:
                print e
        else: # exit thread when job is None
            break
FogleBird
(not directed at anyone in particular) on point 2 - just be aware that if there are multiple consumer threads for a single queue that the producer should put a None for each thread. Or you could use a blocking get with an optional timeout to periodically check the flag (this will also allow periodic housekeeping/heartbeating)
Jeremy Brown