Paster守护进程无法关闭因为无法读取自身pid文件

3 投票
1 回答
1641 浏览
提问于 2025-04-16 20:11

简短总结: 当我让 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。

撰写回答