我有一个用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以外的命令吗?我该如何关闭这个进程呢?
发布于 2012-07-20 20:11:41
我不太习惯使用线程进行编程,但您可以发送SIGINT或其他用户定义的信号,而不是发送kill -9 (对应于SIGKILL)。SIGINT (在我的系统上是kill -2)很好,因为它已经被python理解了。(当python捕捉到该信号时,它会引发一个KeyboardInterrupt),但是任何信号都可以工作。您只需要注册一个干净地退出程序的信号处理程序。
发布于 2012-07-18 23:17:22
在我看来,您正在尝试实现一个守护进程。关于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或其他任何东西来停止它。
发布于 2012-07-18 23:21:55
kill 9是原子驱动的--你不需要自己清理。更好的方法是使用不同的、更温和的信号(例如,HUP通常用于向服务器进程发出关闭时间的信号),并教您的python代码如何优雅地处理它。
signal module documentation应该可以让您入门了。
https://stackoverflow.com/questions/11544553
复制相似问题