Paster守护进程无法关闭因为无法读取自身pid文件
简短总结: 当我让 Paster 停止守护进程时,它无法读取自己用来跟踪进程 ID 的文件。
详细说明:
我在 Windows Vista 上用 Python 2.7.1 运行 Paster(pastescript 1.7.3)。
我第一次惊讶的是在运行一个简单的网站时:
>paster serve development.ini
Starting server in PID 15184.
serving on http://127.0.0.1:5000
我本以为会在同一个文件夹里找到一个叫 paster.pid 的文件,但没有。真奇怪。算了,没关系,我就直接结束那个进程再重新启动。
>paster serve development.ini --pid-file=my.pid
Starting server in PID 20884.
serving on http://127.0.0.1:5000
这次,它创建了一个叫 my.pid 的文件。在另一个命令窗口里,我可以输入:
>type my.pid
20884
网站成功运行,任务管理器也确认有一个 Python 进程在运行,进程 ID 是 20884。
现在,让我们让 paster 报告一下守护进程的状态:
>paster serve development.ini --status --pid-file=my.pid
PID None in my.pid is not running
>type my.pid
20884
奇怪。它声称 my.pid 文件里的 PID 是 None
,但实际上不是。
我们来关闭它。
>paster serve --stop-daemon --pid-file=my.pid
PID in my.pid is not valid (deleting)
>type my.pid
The system cannot find the file specified.
所以,它试图读取 my.pid,但没能读取成功,最后还气得把它删掉了。
与此同时,守护进程还在继续运行。
我不得不手动结束 paster 的守护进程,这也是 @Lennart Regebro 在一个 类似但不那么详细的问题 中推荐的做法。 我希望能把这个过程自动化,作为我测试的一部分,所以我希望能找到一个更好的解决方案。
有什么建议吗?
1 个回答
2
从粘贴脚本的源代码(serve.py
)来看,在读取进程ID(PID)的方法中:
pid = read_pidfile(pidfile)
if pid:
try:
os.kill(int(pid), 0)
return pid
except OSError, e:
if e.errno == errno.EPERM:
return pid
return None
在支持POSIX的系统上,指定0作为信号的意思是只是检查这个进程是否还活着。
但是在Windows上,没有kill
这个系统调用;Python会用TerminateProcess
来代替。所以要么把粘贴脚本中的os.kill
这一行去掉,要么使用一个支持POSIX的系统,比如Cygwin(在Windows上提供POSIX层)或者Linux。