PHP进程同步代码实例


Posted in PHP onFebruary 12, 2015

经常遇到这样一种情况,计划任务定时后台执行某个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 running\n");

}
PHP 相关文章推荐
PHP mail 通过Windows的SMTP发送邮件失败的解决方案
May 27 PHP
需要发散思维学习PHP
Jun 29 PHP
php合并数组中相同元素的方法
Nov 13 PHP
php隐藏IP地址后两位显示为星号的方法
Nov 21 PHP
php为字符串前后添加指定数量字符的方法
May 04 PHP
php开发微信支付获取用户地址
Oct 04 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
Nov 15 PHP
PHP模板引擎Smarty内建函数详解
Apr 11 PHP
非常实用的php验证码类
May 15 PHP
php微信公众平台示例代码分析(二)
Dec 06 PHP
PHP命名空间namespace的定义方法详解
Mar 29 PHP
php获取ajax的headers方法与内容实例
Dec 27 PHP
PHP CURL 内存泄露问题解决方法
Feb 12 #PHP
PHP中捕获超时事件的方法实例
Feb 12 #PHP
php单例模式示例分享
Feb 12 #PHP
PHP 正则表达式小结
Feb 12 #PHP
一个非常完美的读写ini格式的PHP配置类分享
Feb 12 #PHP
PHP动态输出JavaScript代码实例
Feb 12 #PHP
PHP使用JSON和将json还原成数组
Feb 12 #PHP
You might like
ThinkPHP3.2框架使用addAll()批量插入数据的方法
2017/03/16 PHP
PHP中上传文件打印错误错误类型分析
2019/04/14 PHP
Laravel获取所有的数据库表及结构的方法
2019/10/10 PHP
jQuery DOM操作小结与实例
2010/01/07 Javascript
Node.js实战 建立简单的Web服务器
2012/03/08 Javascript
Three.js源码阅读笔记(基础的核心Core对象)
2012/12/27 Javascript
一个简单的弹性返回顶部JS代码实现介绍
2013/06/09 Javascript
jquery中ajax函数执行顺序问题之如何设置同步
2014/02/28 Javascript
JavaScript代码里的判断小结
2016/08/22 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
2017/02/08 Javascript
提高JavaScript执行效率的23个实用技巧
2017/03/01 Javascript
webpack学习教程之前端性能优化总结
2017/12/05 Javascript
基于Vue和Element-Ui搭建项目的方法
2019/09/06 Javascript
JavaScript命令模式原理与用法实例详解
2020/03/10 Javascript
基于Echarts图表在div动态切换时不显示的解决方式
2020/07/20 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
Python的Bottle框架中返回静态文件和JSON对象的方法
2015/04/30 Python
python获取当前运行函数名称的方法实例代码
2017/04/06 Python
python中实现指定时间调用函数示例代码
2017/09/08 Python
Python爬虫实例_利用百度地图API批量获取城市所有的POI点
2018/01/10 Python
Python+tkinter使用40行代码实现计算器功能
2018/01/30 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
python+pyqt5实现图片批量缩放工具
2019/03/18 Python
Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
2019/06/25 Python
8段用于数据清洗Python代码(小结)
2019/10/31 Python
Python实现一个优先级队列的方法
2020/07/31 Python
雅诗兰黛(Estee Lauder)英国官方网站:世界顶级化妆品牌
2016/12/29 全球购物
阿联酋电子产品购物网站:Menakart
2017/09/15 全球购物
法国房车租赁网站:Yescapa
2019/08/26 全球购物
美国折扣地毯销售网站:Rugs.com
2020/03/27 全球购物
渗透攻击的测试步骤
2014/06/07 面试题
高一英语教学反思
2014/01/22 职场文书
售后前台接待岗位职责
2015/04/03 职场文书
婚姻出轨保证书
2015/05/08 职场文书
2015年新农村建设工作总结
2015/05/22 职场文书
Nginx速查手册及常见问题
2022/04/07 Servers