I have a threaded server written in Python that I start using the following shell script:
#!/bin/bash
base_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
public_dns=$(curl -s http://169.254.169.254/latest/meta-data/public-hostname)
echo $public_dns > "$base_path/client/address"
cd "$base_path/server"
python "server.py" &
echo $! > "$base_path/server_pid"
echo "Server running"
I echo the PID to a file so that I can shutdown a server using another shell script:
#!/bin/bash
base_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
kill -9 `cat "$base_path/server_pid"`
rm "$base_path/server_pid"
rm "$base_path/client/address"
I know, however, that this is a bad approach considering the server has many threads that have I/O into network and hdd… So what I would like to do is have the second script somehow interact with the server and tell it to start a shutdown sequence which would cleanly close all the threads, close & archive logs etc.
Now I know about atexit and I tested it this way:
import atexit
def byebye(o):
o.write('stop')
o.flush()
o.close()
o = open('log','w')
o.write('start')
o.flush()
atexit.register(byebye, o)
while True:
pass
But when I kill -9 the process, byebye() is not fired. Should I use a command other than the almighty kill -9? How would I go about shutting down the process?
I’m not particularly used to programming with threads, but rather than sending
kill -9(which corresponds toSIGKILL), you could sendSIGINTor some other user defined signal.SIGINT(kill -2on my system) is nice because that one is already understood by python. (When python catches that signal, it raises aKeyboardInterrupt), but any signal will work. You just need to register a signal handler that exits your program cleanly.