myalert.py
from daemon import Daemon
import os, time, sys
class alertDaemon(Daemon):
def run(self):
while True:
time.sleep(1)
if __name__ == "__main__":
alert_pid = '/tmp/ex.pid'
# if pid doesnt exists run
if os.path.isfile(alert_pid): # is this check enough?
sys.exit(0)
daemon = alertDaemon(alert_pid)
daemon.start()
鉴于没有其他程序或用户会创建pid文件:
1)是否存在pid不存在但守护进程仍在运行的情况? 2)是否存在pid确实存在且守护程序没有运行的情况?
因为如果对上述问题中的至少一个问题的回答是肯定的,那么如果我的目标是一直运行一个守护进程,那么仅仅检查pid文件的存在是不够的。
问:如果我必须检查过程,那么我希望避免像系统调用ps -ef和grep这样的脚本名称。有没有一种标准的方法呢?注意:脚本myalert.py将是一个cronjob
答案 0 :(得分:2)
python-daemon
库,它是PEP 3143的参考实现:“标准守护程序进程库”,通过在pid上使用文件锁(通过lockfile
库)来处理文件传递给DaemonContext
对象。底层操作系统保证在守护程序进程退出时将释放文件锁,即使它已被不正确地退出。这是一个简单的用法示例:
import daemon
from daemon.pidfile import PIDLockFile
context = daemon.DaemonContext(
pidfile= PIDLockFile('/var/run/spam.pid'),
)
with context:
main()
因此,如果新实例启动,则不必确定创建现有pid文件的进程是否仍在通过pid本身运行;如果它可以获取文件锁,则没有其他实例正在运行(因为它们已经获得了锁)。如果它无法获取锁,则必须运行另一个守护进程实例。
遇到麻烦的唯一方法是,如果有人出现并在守护程序运行时手动删除了pid文件。但我认为你不必担心某人故意以这种方式破坏事物。
理想情况下,python-daemon
将成为标准库的一部分,就像PEP 3143的最初目标一样。不幸的是,PEP被推迟了,主要是因为没有人愿意真正做剩余的工作需要得到添加到标准库中:
进一步探讨本PEP所涵盖的概念 因缺乏有兴趣推广的现任冠军而推迟 PEP的目标,收集和整合反馈,以及 足够的时间有效地做到这一点。
答案 1 :(得分:0)
我看到这种方式实施的几种方式:
检查是否存在pid文件 - >如果是这样,请退出并显示错误消息,例如" pid文件存在 - 如果您确定没有进程正在运行,请退出"
检查pidfile是否存在 - >如果是,请检查是否存在具有该pid的进程 - >如果是这样,就告诉用户"进程正在运行.."。冲突的风险(重复用于另一个进程)PID数量非常小,以至于它被忽略了;告诉用户如果发生错误,如何重新启动程序
提示:检查进程是否存在,您可以检查/proc/<pid>
目录
还要确保在脚本退出时尽可能删除pid文件,例如:
将代码换成try .. finally
:
# Check & create pidfile
try:
# your application logic
finally:
# remove pidfile
您甚至可以安装信号处理程序(通过signal
模块),在收到通常不会引发异常的信号时删除pidfile,而是直接退出。