如何检测无响应/冻结的进程?

1 投票
1 回答
4150 浏览
提问于 2025-04-17 17:09

我有几个脚本用来进行网页抓取,它们一直在运行,应该永远不停。但是大约过了一周后,它们就会“卡住”:没有任何输出,也无法通过按Ctrl+C来停止。唯一的办法就是用kill命令结束这个进程,然后重新启动。

我怀疑这个问题可能是因为我用来获取数据的库(urllib2)出了问题,但这个问题很难重现。

所以我在想,怎么能检查这个进程的状态,如果它卡住了,就自动结束并重启它。我考虑过创建一个PID文件,并定期更新它。然后可以用另一个脚本定期检查这个PID文件的最后修改时间,如果时间太久,就重启这个进程。我还可以使用类似Monit的工具来进行监控。

这样做可以吗?有没有其他更好的方法或者常见的方式来检查一个进程是否还在正常工作?

1 个回答

2

如果你有一个一直在运行的程序,它没有连接的终端,并且是进程组的领导者,那它就是一个守护进程(daemon)。你肯定知道这些。

在编写这样的程序时,有一些常见的做法。其中一个就是设置一个信号处理器,它可以接收 SIGHUP 信号,并强制程序重新初始化。这意味着要关闭所有打开的日志文件,重新读取配置脚本等等。我不知道这对你的问题有多大帮助,但在我工作的时候,这有时能解决像守护进程卡住这样的问题。

你还可以通过使用 SIGUSR1SIGUSR2 信号来定制这个想法,做一些特别的事情,比如将状态写入文件,或者其他任何事情。因为信号是通过中断传递的,所以在脚本中的 trap 语句和 Python 自身的信号处理器会把程序的状态推送到中断栈上,并执行一些“操作”。在你的情况下,你可能希望程序自己分叉(fork)并执行,然后杀掉父进程。

撰写回答