PHP實現程式單例運行

來源:互聯網
上載者:User

標籤:php   指令碼   單例   

原創文章,轉載請註明出處:http://huyanping.sinaapp.com/?p=222
Jenner

一、情境描述:

最近我們一塊業務,需要不斷的監聽一個目錄的變化,如果目錄中有檔案,則啟動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='/tmp/'){        if(empty($filename)) throw new JetException('filename cannot be empty...');        $this->filename = $filename;        $this->pid_dir = $pid_dir;        $this->pid_file = $this->pid_dir . DIRECTORY_SEPARATOR . substr(basename($this->filename), 0, -4) . '.pid';    }     /**     * 單例模式啟動介面     * @throws JetException     */    public function single(){        $this->check_pcntl();        if(file_exists($this->pid_file)) {            throw new Exception('the process is already running...');        }        $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, 'w');        if(!$fp){            throw new Exception('cannot create pid file...');        }        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('pcntl_signal')) {            $message = 'PHP does not appear to be compiled with the PCNTL extension.  This is neccesary for daemonization';            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('gc_enable')) {            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();    }}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.