在Google上搜索会显示x2代码段.第一个结果是这个代码配方有很多文档和解释,以及下面的一些有用的讨论.
但是,另一个代码示例虽然不包含如此多的文档,但包含用于传递命令(如启动,停止和重新启动)的示例代码.它还会创建一个PID文件,可以方便地检查守护程序是否已在运行等.
这些示例都解释了如何创建守护进程.还有其他事情需要考虑吗?一个样本比另一个好,为什么?
在成为一个表现良好的守护进程时,有许多需要注意的事情:
防止核心转储(许多守护程序以root身份运行,核心转储可能包含敏感信息)
在chroot
监狱里表现正确
为用例适当地设置UID,GID,工作目录,umask和其他进程参数
放弃提升suid
,sgid
特权
关闭所有打开的文件描述符,具有取决于用例的排除
正确的行为,如果启动一个已经脱离上下文中,如init
,inetd
等
为敏感的守护程序行为设置信号处理程序,但也使用由用例确定的特定处理程序
重定向标准流stdin
,stdout
,stderr
因为守护进程不再具有控制终端
处理一个PID文件作为合作咨询锁,这本身就是一整套蠕虫,有很多矛盾但有效的行为方式
在进程终止时允许适当的清理
实际上成为一个守护进程而不会导致僵尸
其中一些是标准的,如规范的Unix文献(UNIX环境中的高级编程,已故的W. Richard Stevens,Addison-Wesley,1992)中所述.其他的,例如流重定向和PID文件处理,是大多数守护程序用户期望的常规行为,但是标准化程度较低.
所有这些都包含在PEP 3143 "标准守护进程库"规范中.该蟒蛇守护参考实现工作在Python 2.7版或更高版本,和Python 3.2或更高版本.
当前解决方案
PEP 3143(标准守护程序进程库)的参考实现现在可用作python-daemon.
历史答案
Sander Marechal的代码示例优于原始版本,最初发布于2004年.我曾经为Pyro贡献了一个守护程序,但如果我不得不这样做,可能会使用Sander的代码.
这是我开始使用的基本"Howdy World"Python守护进程,当我开发一个新的守护进程应用程序时.
#!/usr/bin/python import time from daemon import runner class App(): def __init__(self): self.stdin_path = '/dev/null' self.stdout_path = '/dev/tty' self.stderr_path = '/dev/tty' self.pidfile_path = '/tmp/foo.pid' self.pidfile_timeout = 5 def run(self): while True: print("Howdy! Gig'em! Whoop!") time.sleep(10) app = App() daemon_runner = runner.DaemonRunner(app) daemon_runner.do_action()
请注意,您需要该python-daemon
库.您可以通过以下方式安装:
pip install python-daemon
然后启动它./howdy.py start
,然后停止它./howdy.py stop
.
注意python-daemon包解决了守护进程背后的许多问题.
它可以实现的其他功能(来自Debian软件包描述):
将进程分离到其自己的进程组中.
设置适合在chroot内运行的进程环境.
放弃suid和sgid权限.
关闭所有打开的文件描述符.
更改工作目录,uid,gid和umask.
设置适当的信号处理程序.
打开stdin,stdout和stderr的新文件描述符.
管理指定的PID锁定文件.
注册清理函数以进行退出处理.
另一种方法 - 创建一个普通的非守护程序的Python程序,然后使用supervisord从外部守护它.这可以节省很多麻烦,并且*nix-和语言可移植.
可能不是问题的直接答案,但systemd可用于将您的应用程序作为守护程序运行.这是一个例子:
[Unit] Description=Python daemon After=syslog.target After=network.target [Service] Type=simple User=Group= ExecStart=/usr/bin/python /script.py # Give the script some time to startup TimeoutSec=300 [Install] WantedBy=multi-user.target
我更喜欢这种方法,因为很多工作都是为您完成的,然后您的守护程序脚本的行为与系统的其他部分类似.
-Orby
YapDi是一个相对较新的python模块,出现在Hacker News中.看起来非常有用,可用于从脚本内部将python脚本转换为守护进程模式.
因为python-daemon还没有支持python 3.x,并且从邮件列表中可以读取的内容,它可能永远不会,我已经编写了PEP 3143的新实现:pep3143daemon
pep3143daemon应该至少支持python 2.6,2.7和3.x.
它还包含一个PidFile类.
该库仅依赖于标准库和六个模块.
它可以用作python-daemon的替代品.
这是文档.