今天有同事问到为什么supervise启动lighttpd的时候,lighttpd的pid文件是空的。我试了下,发现果然如此。

首先猜想是不是supervise动了手脚导致程序getpid得到空值,写了个printf getpid的小例子跑了下发现正常。

后来尝试用supervise启动lighttpd,发现supervise每隔1s就尝试启动lighttpd,即使lighttpd已经正常运行了。用刚才的小例子时不会重复尝试,只有被保护程序挂掉后才尝试重启。

后来突然想到lighttpd的两次fork。由于lighttpd进程是以daemon进程形式运行的,在启动过程中有两次fork子进程,然后父进程退出的操作。

supervise中,启动被监控程序的流程是supervise先fork一个自己,子进程调用execvp来启动被监控程序。父进程记录fork时获得的进程号,监控起来。显然,lighttpd第一次fork后,子进程就已经退出了,故supervise以为被监控进程挂了,于是尝试再次启动lighttpd。由于端口被占用的缘故,lighttpd未能启动,由于lighttpd的启动会清空pid文件,而启动失败又没有往里面写入有效进程号,所以pid文件就是空的了。

不使用supervise,通过普通方式两次启动lighttpd,第二次报端口被占用,此时pid文件为空,验证了以上的推论。

gdb查看结构体更美观

[| 2011/10/09 14:42]
直接p *abc的话会出来一大团东西,好处是最短的垂直空间内能显示完,坏处是层次结构不好找。

在gdb里运行一下set print pretty on
再输出就是层次结构了。
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]