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中文件上传的一个问题
Sep 04 PHP
PHP基础学习小结
Apr 17 PHP
Look And Say 序列php实现代码
May 22 PHP
PHP sprintf() 函数的应用(定义和用法)
Jun 29 PHP
PHP-redis中文文档介绍
Feb 07 PHP
教你如何使用php session
Oct 28 PHP
PHPMailer发送HTML内容、带附件的邮件实例
Jul 01 PHP
thinkPHP实现瀑布流的方法
Nov 29 PHP
php读取和保存base64编码的图片内容
Apr 22 PHP
laravel + vue实现的数据统计绘图(今天、7天、30天数据)
Jul 31 PHP
gearman中任务的优先级和返回状态实例分析
Feb 27 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
Feb 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
PHP集成FCK的函数代码
2008/09/27 PHP
PHP 数据库树的遍历方法
2009/02/06 PHP
PHP 编写大型网站问题集
2010/05/07 PHP
Could not load type System.ServiceModel.Activation.HttpModule解决办法
2012/12/29 PHP
php获取、检查类名、函数名、方法名的函数方法
2015/06/25 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
PHP日志LOG类定义与用法示例
2018/09/06 PHP
详细对比php中类继承和接口继承
2018/10/11 PHP
Laravel 解决composer相关操作提示php相关异常的问题
2019/10/23 PHP
页面中iframe相互传值传参
2009/12/13 Javascript
用JSON做数据传输格式中的一些问题总结
2011/12/21 Javascript
js复制网页内容并兼容各主流浏览器的代码
2013/12/17 Javascript
使用javascript实现雪花飘落的效果
2015/01/13 Javascript
javascript委托(Delegate)blur和focus用法实例分析
2015/05/26 Javascript
javascript垃圾收集机制的原理分析
2016/12/08 Javascript
JavaScript常用正则验证函数实例小结【年龄,数字,Email,手机,URL,日期等】
2017/01/23 Javascript
详解AngularJS跨页面传值(ui-router)
2017/08/23 Javascript
Vuejs开发环境搭建及热更新【推荐】
2018/09/07 Javascript
[01:18:45]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第三场2月1日
2021/03/11 DOTA
详解Python中with语句的用法
2015/04/15 Python
Python利用matplotlib.pyplot绘图时如何设置坐标轴刻度
2018/04/09 Python
python3.6+django2.0+mysql搭建网站过程详解
2019/07/24 Python
python、Matlab求定积分的实现
2019/11/20 Python
tensorflow实现测试时读取任意指定的check point的网络参数
2020/01/21 Python
Python魔术方法专题
2020/06/19 Python
html5 canvas-2.用canvas制作一个猜字母的小游戏
2013/01/07 HTML / CSS
.NET remoting中对象激活的两种方式
2015/06/08 面试题
可靠的数据流传输TCP
2016/03/15 面试题
业务员自荐信范文
2014/04/20 职场文书
汽车广告策划方案
2014/05/31 职场文书
民主生活会对照检查材料范文
2014/10/01 职场文书
2014法院四风问题对照检查材料思想汇报
2014/10/04 职场文书
小学生读书笔记
2015/07/01 职场文书
干货:如何写好工作总结报告!
2019/05/10 职场文书
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis
win10忘记pin密码登录不了怎么办?win10忘记pin密码登不进去的解决方法
2022/07/07 数码科技