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()
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With