搜索
首页php教程php手册PHP实现程序单例运行

PHP实现程序单例运行

 

一、场景描述:

最近我们一块业务,需要不断的监听一个目录的变化,如果目录中有文件,则启动PHP脚本处理掉。最初的方案是使用crontab执行sh脚本,脚本大概如下:

SOK=`ps -ef |grep /www/sender.sh | grep -v grep|wc -l`
if [[ $SOK < 2 ]];then
        for f in `ls /www/queue`; do
                        php /www/logsender.php /www/queue/$f
        done


实际运行中出现了异常:ps -ef | grep xxx的方式,可能无法正确的判断进程是否正在执行,if条件永远都不会成立,使得PHP脚本永远不会执行。经过考虑后,决定建立一个独立于其他模块的,能够实现进程单例运行的类,解决这个问题。

二、方案设计

1、通过PID文件实现进程单例

2、程序启动、退出自动创建、删除PID文件,做到不需要业务代码考虑PID文件删除

3、尽量保证代码独立性,不影响业务代码

三、原理

1、启动创建PID文件

2、绑定程序退出、被杀死等信号量,用于删除PID文件

3、添加析构函数,对象被销毁时,删除PID文件

四、遇到的问题

程序正常退出时,无法捕获到信号量,不知道是不是信号量选错了,ctrl+c等信号是正常的,如果可以解决捕获程序正常退出时的信号量,则可以替代析构函数方案,更加稳定

五、代码
 

<!--?php
/**
 * Created by PhpStorm.
 * User: huyanping
 * Date: 14-8-13
 * Time: 下午2:25
 *
 * 实现程序单例运行,调用方式:
 * declare(ticks = 1);//注意:一定要在外部调用文件中首部调用该声明,否则程序会无法监听到信号量
 * $single = new DaemonSingle(__FILE__);
 * $single--->single();
 *
 */
 
class DaemonSingle {
 
    //PID文件路径
    private $pid_dir;
 
    //PID文件名称
    private $filename;
 
    //PID文件完整路径名称
    private $pid_file;
 
    /**
     * 构造函数
     * @param $filename
     * @param string $pid_dir
     */
    public function __construct($filename, $pid_dir=&#39;/tmp/&#39;){
        if(empty($filename)) throw new JetException(&#39;filename cannot be empty...&#39;);
        $this->filename = $filename;
        $this->pid_dir = $pid_dir;
        $this->pid_file = $this->pid_dir . DIRECTORY_SEPARATOR . substr(basename($this->filename), 0, -4) . &#39;.pid&#39;;
    }
 
    /**
     * 单例模式启动接口
     * @throws JetException
     */
    public function single(){
        $this->check_pcntl();
        if(file_exists($this->pid_file)) {
            throw new Exception(&#39;the process is already running...&#39;);
        }
        $this->create_pid_file();
    }
 
    /**
     * @throws JetException
     */
    private function create_pid_file()
    {
        if (!is_dir($this->pid_dir)) {
            mkdir($this->pid_dir);
        }
        $fp = fopen($this->pid_file, &#39;w&#39;);
        if(!$fp){
            throw new Exception(&#39;cannot create pid file...&#39;);
        }
        fwrite($fp, posix_getpid());
        fclose($fp);
        $this->pid_create = true;
    }
 
    /**
     * 环境检查
     * @throws Exception
     */
    public function check_pcntl()
    {
        // Make sure PHP has support for pcntl
        if (!function_exists(&#39;pcntl_signal&#39;)) {
            $message = &#39;PHP does not appear to be compiled with the PCNTL extension.  This is neccesary for daemonization&#39;;
            throw new Exception($message);
        }
        //信号处理
        pcntl_signal(SIGTERM, array(&$this, signal_handler));
        pcntl_signal(SIGINT, array(&$this, signal_handler));
        pcntl_signal(SIGQUIT, array(&$this, signal_handler));
 
        // Enable PHP 5.3 garbage collection
        if (function_exists(&#39;gc_enable&#39;)) {
            gc_enable();
            $this->gc_enabled = gc_enabled();
        }
    }
 
    /**
     * 信号处理函数,程序异常退出时,安全删除PID文件
     * @param $signal
     */
    public function signal_handler($signal)
    {
        switch ($signal) {
            case SIGINT :
            case SIGQUIT:
            case SIGTERM:{
                self::safe_quit();
                break;
            }
        }
    }
 
    /**
     * 安全退出,删除PID文件
     */
    public function safe_quit()
    {
        if (file_exists($this->pid_file)) {
            $pid = intval(posix_getpid());
            $file_pid = intval(file_get_contents($this->pid_file));
            if($pid == $file_pid){
                unlink($this->pid_file);
            }
        }
        posix_kill(0, SIGKILL);
        exit(0);
    }
 
    /**
     * 析构函数,删除PID文件
     */
    public function __destruct(){
            $this->safe_quit();
    }
}



 

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),