3

我有一个用 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()并没有被解雇。我应该使用全能kill -9以外的命令吗?我将如何关闭该过程?

4

3 回答 3

5

在我看来,您正在尝试实现一个守护进程。关于 python 中的守护进程实现有各种参考:

上一个 stackoverlow 问题: 如何在 Python 中创建守护进程?

PEP 关于守护进程:http: //www.python.org/dev/peps/pep-3143/

python模块实现PEP3143: 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-18T15:17:21.957 回答
1

kill 9是原子动力的——你不需要自己清理。更好的方法是使用不同的、更温和的信号(HUP例如,通常用于向服务器进程发出信号表明该关闭了),并教你的 python 代码如何优雅地处理它。

信号模块文档应该可以帮助您入门。

于 2012-07-18T15:21:55.267 回答
1

我不是特别习惯于使用线程进行编程,但不是发送kill -9(对应于SIGKILL),您可以发送SIGINT或其他一些用户定义的信号。 SIGINTkill -2在我的系统上)很好,因为 python 已经理解了。(当 python 捕获该信号时,它会引发 a KeyboardInterrupt),但任何信号都可以工作。您只需要注册一个干净地退出程序的信号处理程序。

于 2012-07-20T12:11:41.397 回答