我有一个用Python编写的线程服务器,我开始使用以下shell脚本:
#!/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"
我将PID回显到一个文件,以便我可以使用另一个shell脚本关闭服务器:
#!/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 / O进入网络和硬盘......所以我想做的是让第二个脚本以某种方式与服务器进行交互告诉它启动一个关闭序列,它将干净地关闭所有线程,关闭&存档日志等。
现在我知道atexit并且我用这种方式测试了它:
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
但是当我kill -9
这个过程时,byebye()
没有被解雇。我应该使用almighty kill -9
以外的命令吗?我该如何关闭这个过程?
答案 0 :(得分:5)
在我看来,你正试图实现一个守护进程。 有关python中守护进程实现的各种参考:
上一次stackoverlow问题: How do you create a daemon in Python?
关于守护进程的PEP: http://www.python.org/dev/peps/pep-3143/
实现PEP3143的python模块: http://pypi.python.org/pypi/python-daemon/
请注意,PEP是草案。
有关守护进程的更多信息:http://en.wikipedia.org/wiki/Daemon_%28computing%29
通常,守护程序启动,停止并重新启动为:
mydaemon start
mydaemon stop
mydaemon restart
所以你不需要知道PID或其他任何东西来阻止它。
答案 1 :(得分:1)
kill 9
是原子动力的 - 你不能自己清理。更好的方法是使用一个不同的,更温和的信号(例如,HUP
通常用于向服务器进程发出关闭时间的信号),并教你的python代码如何优雅地处理它。
signal module documentation应该让你开始。
答案 2 :(得分:1)
我并不是特别习惯用线程编程,而是发送kill -9
(对应SIGKILL
),而不是发送SIGINT
或其他一些用户定义的信号。 SIGINT
(我的系统上的kill -2
)很好,因为python已经理解了它。 (当python捕获到该信号时,它会引发KeyboardInterrupt
),但任何信号都会起作用。您只需要注册一个完全退出程序的信号处理程序。