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的memory_limit限制的方法分享
Feb 21 PHP
php将gd生成的图片缓存到memcache的小例子
Jun 05 PHP
php_screw 1.5:php加密: 安装与使用详解
Jun 20 PHP
那些年我们错过的魔术方法(Magic Methods)
Jan 14 PHP
ThinkPHP3.1查询语言详解
Jun 19 PHP
php上传图片并压缩的实现方法
Dec 22 PHP
Zend Framework教程之Autoloading用法详解
Mar 08 PHP
PHP的Laravel框架结合MySQL与Redis数据库的使用部署
Mar 21 PHP
PHP购物车类Cart.class.php定义与用法示例
Jul 20 PHP
PHP7标量类型declare用法实例分析
Sep 26 PHP
PHP+Ajax实现的博客文章添加类别功能示例
Mar 29 PHP
PHP类与对象后期静态绑定操作实例详解
Dec 20 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
超神学院:鹤熙已踏入神圣领域,实力不比凯莎弱
2020/03/02 国漫
php中长文章分页显示实现代码
2012/09/29 PHP
PHP导出EXCEL快速开发指南--PHPEXCEL的使用详解
2013/06/03 PHP
PHP采用XML-RPC构造Web Service实例教程
2014/07/16 PHP
Yii使用smsto短信接口的函数demo示例
2016/07/13 PHP
JS+PHP实现用户输入数字后显示最大的值及所在位置
2017/06/19 PHP
多种方法实现JS动态添加事件
2013/11/01 Javascript
jQuery中:radio选择器用法实例
2015/01/03 Javascript
Javascript之Number对象介绍
2016/06/07 Javascript
基于JS代码实现导航条弹出式悬浮菜单
2016/06/17 Javascript
jQuery阻止移动端遮罩层后页面滚动
2017/03/15 Javascript
JavaScript之iterable_动力节点Java学院整理
2017/06/29 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
快速搭建vue2.0+boostrap项目的方法
2018/04/09 Javascript
JavaScript实现简单的文本逐字打印效果示例
2018/04/12 Javascript
Webpack4+Babel7+ES6兼容IE8的实现
2019/04/10 Javascript
mpvue性能优化实战技巧(小结)
2019/04/17 Javascript
小程序如何定位所在城市及发起周边搜索
2020/02/11 Javascript
微信小程序获取公众号文章列表及显示文章的示例代码
2020/03/10 Javascript
小程序自定义弹框效果
2020/11/16 Javascript
pymongo实现多结果进行多列排序的方法
2015/05/16 Python
python3转换code128条形码的方法
2019/04/17 Python
Pytorch中的variable, tensor与numpy相互转化的方法
2019/10/10 Python
Python如何实现动态数组
2019/11/02 Python
Python基于time模块表示时间常用方法
2020/06/18 Python
Django ORM判断查询结果是否为空,判断django中的orm为空实例
2020/07/09 Python
Zooplus罗马尼亚:宠物食品和配件
2019/11/02 全球购物
Linux的主要特性
2016/09/03 面试题
高校毕业生自我鉴定
2013/10/27 职场文书
优秀幼教自荐信
2014/02/03 职场文书
求职自我推荐信
2014/06/25 职场文书
2014新生大学四年计划书
2014/09/21 职场文书
朋友聚会祝酒词
2015/08/10 职场文书
Python快速优雅的批量修改Word文档样式
2021/05/20 Python
Python激活Anaconda环境变量的详细步骤
2021/06/08 Python
详解Golang如何优雅的终止一个服务
2022/03/21 Golang