Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python how to kill threads blocked on queue with signals?

I start a bunch of threads working on a queue and I want to kill them when sending the SIGINT (Ctrl+C). What is the best way to handle this?

targets = Queue.Queue()
threads_num = 10
threads = []

for i in threads_num:
    t = MyThread()
    t.setDaemon(True)
    threads.append(t)
    t.start()

targets.join()
like image 497
gbr Avatar asked Sep 30 '11 12:09

gbr


People also ask

How do you force kill a thread in Python?

In order to kill a thread, we use hidden function _stop() this function is not documented but might disappear in the next version of python.

How do I force a thread to kill?

The start() method can then be called to run the new process and new main thread. Back in the main thread of our first process, we will block for a while to let the new task run. We can then forcefully kill the new main thread by calling the terminate() function on the thread's parent process.

How do you end a queue in Python?

Queue's don't inherently have the idea of being complete or done. They can be used indefinitely. To close it up when you are done, you will indeed need to put None or some other magic value at the end and write the logic to check for it, as you described. The ideal way would probably be subclassing the Queue object.

How do you block a thread in Python?

One thread can block when waiting for another thread to terminate. This is achieved by the waiting thread calling the join() function on the other running thread. This function call will block until the other thread finishes, or returns immediately if the thread has already terminated.


1 Answers

If you are not interested in letting the other threads shut down gracefully, simply start them in daemon mode and wrap the join of the queue in a terminator thread.

That way, you can make use of the join method of the thread -- which supports a timeout and does not block off exceptions -- instead of having to wait on the queue's join method.

In other words, do something like this:

term = Thread(target=someQueueVar.join)
term.daemon = True
term.start()
while (term.isAlive()):
    term.join(3600)

Now, Ctrl+C will terminate the MainThread whereupon the Python Interpreter hard-kills all threads marked as "daemons". Do note that this means that you have to set "Thread.daemon" for all the other threads or shut them down gracefully by catching the correct exception (KeyboardInterrupt or SystemExit) and doing whatever needs to be done for them to quit.

Do also note that you absolutely need to pass a number to term.join(), as otherwise it will, too, ignore all exceptions. You can select an arbitrarily high number, though.

like image 83
HedAurabesh Avatar answered Nov 15 '22 16:11

HedAurabesh