深窥自己的心,而后发觉一切的奇迹在你自己。 --培根
写在前面的话
在前面的博客我曾经写过关于定时任务的相关的内容,既然是定时任务,那么我们就希望它能够自己执行,所以我便想到了用一个守护进程来管理这些任务,让它能够在正确的时间做正确的事情,那么问题来了,如果想让进程一直跑,就算你断掉终端它也要跑,这个并不像单纯的执行那么简单。经过不懈的努力总算找到了解决办法。本文是一篇译文,原文请看 Stack Overflow,原贴中提到诸多方法,而我比较喜欢的是下面两种,分别是:
方法一:借助nohup
你应该用下面的命令来运行你的PHP源码:
nohup php myscript.php &
其中&
作用就是将当前任务变成一个后台运行的任务,当然,这种方式也是有缺点的,不过如果你认为这样的方式,让你没法控制你的脚本,那你就大错特错了,最简单的也是最棒的一种方式kill processid
,这样就可以终止程序的运行。
方法二:借助PHP库
如果可以的话,你可以购买一本Advanced Programming in the UNIX Environment,这本书整个13章都在用C为例子讲解守护进程,如果你想用PHP写守护进程,你得借助PHP封装好的一些扩展来实现(例如: pcntl和posix)。
按照下文的方式,寥寥几步你就可以完成守护进程的改编:
- 调用
umask(0)
来解决权限相关的问题 - 使用
fork()
函数,创建一个子进程,同时退出父进程 - 调用
setsid()
- 设置程序的信号处理一般会设置
SIGHUP
(这个信号一般是用来告诉守护进程重新加载它的配置)和SIGTERM
(这个信号一般是用来优雅的结束守护进程的) - 再次
fork()
一个子进程,同时退出父进程 - 用
chdir()
来改变当前的工作目录 - 像
fclose()
、stdin
、stdout
和stderr
这几个有输出的情况,不建议直接输出,正确的做法就是将输出信息重定向到/dev/null
或者一个文件中,但是可惜的是我并没有在PHP中找到相应的解决方案,比较靠谱的做法是,你在启动这个守护进程的时候在shell中将输出重定向(这件事情得你自己想办法解决了,因为我也不怎么会) - 你成功了么?
另外,在你使用PHP的时候,因为其垃圾回收机制,你不得不注意循环的引用,在PHP5.3之前的版本中,没办法收集引用的相关信息,导致程序出现内存泄漏,最终彻底崩溃。
最后说两句,图方便的就用方法一吧,技术控试试方法二,如果你有更好的方法欢迎留言哦!^_^
本文由 陌上花开 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jul 1, 2016 at 06:53 am