Best way to signal other threads to exit upon exiting bokeh server?

A thread in a bokeh serve script needs an exit signal to gracefully exit. Stopping bokeh serve from command line with ctrl-C works but the thread hangs, preventing the complete exit.

I typically signal multiple threads via Python Events when KeyboardInterrupt exception is detected, like this:

try:
    run_multiple_threads()
except KeyboardInterrupt as err:
    e.set() # all threads exit!
    sys.exit()

This isn’t working with bokeh serve. It seems that run_until_shutdown() catches the KeyboardInterrupt but returns nothing.

What’s the best way to tell other threads to exit when Bokeh server exits?

Have you tried marking your threads as daemon?
From https://docs.python.org/3/library/threading.html#thread-objects:

Hello @p-himik,

Great idea. I had forgotten that option. This works perfectly. Now the thread will exit when Bokeh captures the ctrl+c at the command line.

Thanks,
Marc

It is generally a bad pattern to kill a thread abruptly, in Python, and in any language. Think of the following cases:

  • the thread is holding a critical resource that must be closed properly
  • the thread has created several other threads that must be killed as well.

If you REALLY need to use a Thread, there is no way to kill thread directly. What you can do, however, is to use a “daemon thread”. In fact, in Python, a Thread can be flagged as daemon:

If you do NOT really need to have a Thread , what you can do, instead of using the threading package , is to use the multiprocessing package . Here, to kill a process, you can simply call the method:

yourProcess.terminate()

Python will kill your process (on Unix through the SIGTERM signal, while on Windows through the TerminateProcess() call). Pay attention to use it while using a Queue or a Pipe! (it may corrupt the data in the Queue/Pipe)

1 Like

Thanks @larryhems , I’ll review this option, for sure. I like the multiprocessing library and use it and threads as-needed.

This problem was solved earlier from @p-himik’s post but this is helpful also.