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制作简单的内容采集器的原理分析
Oct 01 PHP
PHP之COOKIE支持详解
Sep 20 PHP
PHP OPCode缓存 APC详细介绍
Oct 12 PHP
php数组函数序列之array_splice() - 在数组任意位置插入元素
Nov 07 PHP
php数组函数序列之array_pop() - 删除数组中的最后一个元素
Nov 07 PHP
php实现的ping端口函数实例
Nov 12 PHP
Linux系统递归生成目录中文件的md5的方法
Jun 29 PHP
详解PHP数据压缩、加解密(pack, unpack)
Dec 17 PHP
PHP使用imagick扩展实现合并图像的方法
Apr 25 PHP
详解PHP函数 strip_tags 处理字符串缺陷bug
Jun 11 PHP
PHP迭代器和迭代的实现与使用方法分析
Apr 19 PHP
如何在Laravel之外使用illuminate组件详解
Sep 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
一个好用的PHP验证码类实例分享
2013/12/27 PHP
PHP中使用正则表达式提取中文实现笔记
2015/01/20 PHP
ThinkPHP中Widget扩展的两种写法及调用方法详解
2017/05/04 PHP
PHP5.0~5.6 各版本兼容性cURL文件上传功能实例分析
2018/05/11 PHP
jQuery使用animate创建动画用法实例
2015/08/07 Javascript
基于jQuery实现的仿百度首页滑动选项卡效果代码
2015/11/16 Javascript
下一代Bootstrap的5个特点 超酷炫!
2016/06/17 Javascript
解决Node.js使用MySQL出现connect ECONNREFUSED 127.0.0.1:3306的问题
2017/03/09 Javascript
Vue键盘事件用法总结
2017/04/18 Javascript
微信小程序模板和模块化用法实例分析
2017/11/28 Javascript
JavaScript实现计算多边形质心的方法示例
2018/01/31 Javascript
在vue2.0中引用element-ui组件库的方法
2018/06/21 Javascript
js与jQuery实现获取table中的数据并拼成json字符串操作示例
2018/07/12 jQuery
Vue.js中的组件系统
2019/05/30 Javascript
浅析vue-cli3配置webpack-bundle-analyzer插件【推荐】
2019/10/23 Javascript
JavaScript 常见的继承方式汇总
2020/09/17 Javascript
[57:28]2018DOTA2亚洲邀请赛 4.6 淘汰赛 TNC vs Liquid 第一场
2018/04/10 DOTA
[34:39]Secret vs VG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
Python MySQLdb Linux下安装笔记
2015/05/09 Python
Python二叉搜索树与双向链表转换实现方法
2016/04/29 Python
使用PyInstaller将Python程序文件转换为可执行程序文件
2016/07/08 Python
Python实现的人工神经网络算法示例【基于反向传播算法】
2017/11/11 Python
python使用turtle库与random库绘制雪花
2018/06/22 Python
python读取几个G的csv文件方法
2019/01/07 Python
Python实现的读取文件内容并写入其他文件操作示例
2019/04/09 Python
Python爬虫动态ip代理防止被封的方法
2019/07/07 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
2019/07/12 Python
Python脚本操作Excel实现批量替换功能
2019/11/20 Python
构建高效的python requests长连接池详解
2020/05/02 Python
Python批量删除mysql中千万级大量数据的脚本分享
2020/12/03 Python
琳达·法罗眼镜英国官网:Linda Farrow英国
2021/01/19 全球购物
4s店总经理岗位职责
2013/12/31 职场文书
沙滩主题婚礼活动策划方案
2014/09/15 职场文书
2016公司年会主持词
2015/07/01 职场文书
浅谈Java实现分布式事务的三种方案
2021/06/11 Java/Android
OpenCV实现常见的四种图像几何变换
2022/04/01 Python