You are creating an http server process but not join() it. What happens if, instead of running os.kill() , to stop the http server process, you send it a breakpoint ( None , like you send workers), and then do self.http.join() ?
Refresh . You also need to send a None watchdog request to the input queue once for each worker . You can try:
for w in self.workers: self.i_queue.put(None) for w in self.workers: w.join()
NB The reason you need two loops is because if you put None in the queue in the same loop that join() does, then None can be raised by a worker other than w , so joining in w will result in a lock the caller.
You do not show the code for workers or an http server, so I assume that they behave well in terms of calling task_done, etc. and that every employee will leave as soon as he sees None , without get() -fetching any things from the input queue.
Also, note that there is one open hard-replication JoinableQueue.task_done() with JoinableQueue.task_done() that may bite you.
source share