程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP進程同步代碼實例

PHP進程同步代碼實例

編輯:關於PHP編程

     這篇文章主要介紹了PHP進程同步代碼實例,本文直接給出實現代碼,需要的朋友可以參考下

       

    經常遇到這樣一種情況,計劃任務定時後台執行某個php程序,有時候也需要手動執行,可能多個人都需要執行這個程序,如果任務持續時間非常長,就很容易造成重復執行,所以就開發了下面的類。

    作用:在實際代碼運行前檢查與當前相同操作的進程是否正在運行,高並發運行是可靠的,運行中的進程中途異常中斷不會產生任何影響。

    構造方法傳遞pid文件目錄的絕對路徑,需要自己保證不同進程對應不同pid文件。

     

    代碼如下:
    <?php

     

    /*
    * 同一個PHP進程只運行一次,根據進程名字判斷是否為排重進程,只能運行於linux,高並發條件下是並發安全的。
    */

    class SyncProcess {

    private $pidFile;

    function __construct($pidFile) {
    $this->pidFile = $pidFile;
    }

    /**
    * 非阻塞方式返回進程是否正在運行
    */
    function check() {
    if (PHP_OS == 'Linux') {
    $pidFile = $this->pidFile;
    if (!empty($pidFile)) {
    $flag = false;
    $pidDir = dirname($pidFile);
    if (is_dir($pidDir)) {
    $flag = true;
    }
    if ($flag) {
    $running = true;
    clearstatcache(true, $this->pidFile);
    if (!file_exists($this->pidFile))
    file_put_contents($this->pidFile, '', LOCK_EX);
    $f = fopen($this->pidFile, 'r+');
    if (flock($f, LOCK_EX ^ LOCK_NB)) {
    $pid = trim(fgets($f));
    if (!$this->is_process_running($pid)) {
    $running = false;
    }
    }
    if (!$running) {
    fseek($f, 0);
    ftruncate($f, 0);
    fwrite($f, getmypid());
    }
    flock($f, LOCK_UN);
    fclose($f);
    return $running;
    } else {
    debug_print("pid file($pidFile) is invalid", E_USER_WARNING);
    }
    } else {
    debug_print("pid file cant't be empty", E_USER_WARNING);
    }
    } else {
    debug_print(__CLASS__ . ' can only run in Linux', E_USER_WARNING);
    return true;
    }
    }

    /**
    * 如果正在運行或者發生未知錯誤返回true,如果沒有運行返回false
    * @param mixed $pid
    */
    private function is_process_running($pid) {
    if (is_numeric($pid) && $pid > 0) {
    $output = array();
    $line = exec("ps -o pid --no-headers -p $pid", $output);
    //返回值有空格
    $line = trim($line);
    if ($line == $pid) {
    return true;
    } else {
    if (empty($output)) {
    return false;
    } else {
    if (php_sapi_name() == 'cli')
    $n = "n";
    else
    $n = "<br>";
    //到這一步的話應該是出什麼問題了
    $output = implode($n, $output);
    debug_print($output, E_USER_WARNING);
    return true;
    }
    }
    }else {
    return false;
    }
    }

    }

     

    Demo:

     

    代碼如下:
    $sync = new SyncProcess(APP_PATH . '/data/pid'.implode('', $this->getRoute()));
    if ($sync->check()) {
    exit("process is runningn");
    }
    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved