0

Issues

I currently have a simple Python multithreaded server program, which will run forever with out manual interruption. I want to achieve that it can be terminated gracefully at some point. Once it is terminated, I want the server to output some stats.

Solutions I have tried

  1. Terminate the program by kill. The issue is that the server cannot output the stats because the HARD termination.
  2. Create a control thread in the program, which listens the key input. And if key is pressed, then terminate the program and get stats. The issue with this approach is I need to do every step manually. E.g, SSH to the device, start the program, and press key at some point.

Question

Is there a way that I can run some bash/or other program to stop the program gracefully with stats output?

jiashenC
  • 1,812
  • 2
  • 16
  • 31
  • 1
    Possible duplicate of [How to exit a multithreaded program?](https://stackoverflow.com/questions/5849484/how-to-exit-a-multithreaded-program) – ivan_pozdeev Sep 01 '18 at 22:06
  • 1
    I don't think so. My point is I know how to stop all running threads in my Python program. I want the server be terminated by some external signals. Otherwise, I will let the server keep running. – jiashenC Sep 01 '18 at 22:11
  • In that case, you can catch an external signal from within and then gracefully exit from the thread. Either way, for a graceful exit, you have to implement the exiting functionality in the thread itself, by reading some flag. – zvone Sep 01 '18 at 22:27

2 Answers2

1

Have you tried to use signal.signal() to register a handler for e.g. SIGTERM? There you could implement this part of code that throws out the statistics and then just terminate the program.

1

The standard approach is to either

  • make threads sufficiently short-lived
  • at the stop signal, stop spawning new ones and .join() the active ones.

or

  • make threads periodically (e.g. after serving each request) check some shared stop flag and quit when it's set
  • at the stop signal, set the stop flag, then .join() the threads

Some threads can be .setDaemon(True), but only if they can be safely killed off (there's no exception or anything raised in the thread, it's just stopped where it is).

If a thread is in a blocking call, it may be possible to unblock it by shutting down the facility that it is waiting on (close the socket or the stream).

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152