粘贴守护程序无法关闭,因为无法读取自己的pid文件。

3

TL;DR版本: 当我要求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

网站已成功提供服务,任务管理器确认有一个PID为20884的Python进程正在运行。

现在,让我们要求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.

因此,它试图读取我的.pid文件,但无法读取,并感到沮丧而将其删除。

与此同时,守护程序继续运行。

我必须手动杀死paster守护程序,这是@Lennart Regebro在一个类似但不够详细的问题中推荐的方法。我希望能找到更干净的解决方案来自动化这个过程作为我的测试的一部分。

有什么建议吗?

1个回答

2

从粘贴脚本的源代码(serve.py)中,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代替。从paster脚本中删除os.kill行或使用一个POSIX兼容的平台,如Cygwin(在Windows上的POSIX层)或Linux。

1
总结一下以确保我清楚:在POSIX平台上,os.kill(pid,0)不会杀死进程,但在Windows上使用的TerminateProcess shiv上会杀死进程(自Python 2.7以来,这可能是Paster 1.7.3没有修复它的原因)。唉,这是一个尴尬的情况。 - Oddthinking
1
@Oddthinking 没错。kill这个名字是误导性的,它实际上只是发送一个信号。然而,大多数信号恰好与中断/终止进程有关。 - phihag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接