当前位置:首页 > PHP教程 > php应用 > 列表

PHP进程同步代码实例

发布:smiling 来源: PHP粉丝网  添加日期:2021-05-13 11:44:38 浏览: 评论:0 

这篇文章主要介绍了PHP进程同步代码实例,本文直接给出实现代码,需要的朋友可以参考下

经常遇到这样一种情况,计划任务定时后台执行某个php程序,有时候也需要手动执行,可能多个人都需要执行这个程序,如果任务持续时间非常长,就很容易造成重复执行,所以就开发了下面的类。

作用:在实际代码运行前检查与当前相同操作的进程是否正在运行,高并发运行是可靠的,运行中的进程中途异常中断不会产生任何影响。

构造方法传递pid文件目录的绝对路径,需要自己保证不同进程对应不同pid文件。

代码如下:

  1. <?php 
  2. /* 
  3.  * 同一个PHP进程只运行一次,根据进程名字判断是否为排重进程,只能运行于linux,高并发条件下是并发安全的。 
  4.  */ 
  5.  
  6. class SyncProcess { 
  7.  
  8.  private $pidFile
  9.  
  10.  function __construct($pidFile) { 
  11.   $this->pidFile = $pidFile
  12.  } 
  13.  
  14.  /** 
  15.   * 非阻塞方式返回进程是否正在运行 
  16.   */ 
  17.  function check() { 
  18.   if (PHP_OS == 'Linux') { 
  19.    $pidFile = $this->pidFile; 
  20.    if (!emptyempty($pidFile)) { 
  21.     $flag = false; 
  22.     $pidDir = dirname($pidFile); 
  23.     if (is_dir($pidDir)) { 
  24.      $flag = true; 
  25.     } 
  26.     if ($flag) { 
  27.      $running = true; 
  28.      clearstatcache(true, $this->pidFile); 
  29.      if (!file_exists($this->pidFile)) 
  30.       file_put_contents($this->pidFile, '', LOCK_EX); 
  31.      $f = fopen($this->pidFile, 'r+'); 
  32.      if (flock($f, LOCK_EX ^ LOCK_NB)) { 
  33.       $pid = trim(fgets($f)); 
  34.       if (!$this->is_process_running($pid)) { 
  35.        $running = false; 
  36.       } 
  37.      } 
  38.      if (!$running) { 
  39.       fseek($f, 0); 
  40.       ftruncate($f, 0); 
  41.       fwrite($fgetmypid()); 
  42.      } 
  43.      flock($f, LOCK_UN); 
  44.      fclose($f); 
  45.      return $running
  46.     } else { 
  47.      debug_print("pid file($pidFile) is invalid", E_USER_WARNING); 
  48.     } 
  49.    } else { 
  50.     debug_print("pid file cant't be empty", E_USER_WARNING); 
  51.    } 
  52.   } else { 
  53.    debug_print(__CLASS__ . ' can only run in Linux', E_USER_WARNING); 
  54.    return true; 
  55.   } 
  56.  } 
  57.  
  58.  /** 
  59.   * 如果正在运行或者发生未知错误返回true,如果没有运行返回false 
  60.   * @param mixed $pid 
  61.   */ 
  62.  private function is_process_running($pid) { 
  63.   if (is_numeric($pid) && $pid > 0) { 
  64.    $output = array(); 
  65.    $line = exec("ps -o pid --no-headers -p $pid"$output); 
  66.    //返回值有空格 
  67.    $line = trim($line); 
  68.    if ($line == $pid) { 
  69.     return true; 
  70.    } else { 
  71.     if (emptyempty($output)) { 
  72.      return false; 
  73.     } else { 
  74.      if (php_sapi_name() == 'cli'
  75.       $n = "\n"
  76.      else 
  77.       $n = "<br>"
  78.      //到这一步的话应该是出什么问题了 
  79.      $output = implode($n$output); 
  80.      debug_print($output, E_USER_WARNING); 
  81.      return true; 
  82.     } 
  83.    } 
  84.   }else { 
  85.    return false; 
  86.   } 
  87.  } 
  88.  

Demo:

  1. $sync = new SyncProcess(APP_PATH . '/data/pid'.implode(''$this->getRoute())); 
  2. if ($sync->check()) { 
  3.  exit("process is running\n"); 
  4. }

Tags: PHP进程同步

分享到: