CLI下另一种多进程实现方式----PCNTL

有些时候,你需要对一些脚本进行优化,以期跑的更快,在更短的时间内完成任务。PCNTL是一个不错的选择,它可以fork多个进程,来协同完成一个任务,理论上完成的时间将会和进程数成反比。

不过,PCNTL只能用于CLI模式下,不能用于Web服务器环境,否则可能会带来意料之外的错误,不推荐使用。

  • 安装PCNTL扩展:

    wget http://cn2.php.net/distributions/php-5.3.27.tar.bz2
    tar -jxvf php-5.3.27.tar.bz2
    cd php-5.3.27/ext/pcntl/
    phpize && ./configure && make install
    echo "extension=pcntl.so" >> /application/php5.3.27/lib/php.ini
    kill -USR2 `cat /var/run/php-fpm.pid`
    下载->解压->编译->添加扩展模块->重启php-fpm

    注意:线上web服务器中,PHP编译时已经集成该函数,不需要再单独添加,否则会报warning。

    • 程序实例:

      程序流程在注释中已经比较详细的说明了,这里不再单独叙述。
    • 执行结果:

      从结果中可以看出来,虽然程序中fork子进程是有序的,但是在实际执行中并不一定是有序的,进程完成的顺序与进程开始的顺序也不是保持一致的。
      fork前,子进程可以继承父进程的东西,但是在pcntl_fork()后子进程和父进程就没有任何继承关系了。在子进程里创建的东西是子进程的,在父进程创建的东西是父进程的,可以完全看成是两个独立的进程。
      fork后,程序出了分岔,派生出了两个进程,具体哪个先运行,哪个先结束就看该系统的调度算法了。
    • demo
    • <?php
      /**
       * pcntl test
       * @author: xxxx
       */
      
      set_time_limit(0);
      
      //如果找不到pcntl_fork函数,直接退出
      if (! function_exists(‘pcntl_fork‘)) echo "PCNTL functions not available on this PHP installation\n";
      
      //脚本运行开始
      $start =  time();
      echo "\nSCRIT RUN AT: ", date(‘Y-m-d H:i:s‘, $start), "\n";
      
      //从CLI取参数
      //默认跑10个进程
      $pmax = empty($argv[1]) ? 10 : $argv[1];
      //父进程pid
      $ppid = getmypid();
      for ($i = 1; $i <= $pmax; ++$i) {
          //开始产生子进程
          $pid = pcntl_fork();
          switch ($pid) {
          case -1:
              // fork失败
              echo "Fork failed!\n";
              break;
          case 0:
              // fork成功,并且子进程会进入到这里
              sleep(1);
              $cpid = getmypid(); //用getmypid()函数获取当前进程的PID
              echo "FORK: Child #{$i} #{$cpid} is running...\n";
              //子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程
              exit($i);
              break;
          default:
              // fork成功,并且父进程会进入到这里
              if ($i == 1) {
                  echo "Parent #{$ppid} is running...\n";
              }
              break;
         }
      }
      
      //父进程利用while循环,并且通过pcntl_waitpid函数来等待所有子进程完成后才继续向下进行
      while (pcntl_waitpid(0, $status) != -1) {
          //pcntl_wexitstatus返回一个中断的子进程的返回代码,由此可判断是哪一个子进程完成了
          $status = pcntl_wexitstatus($status);
          echo "Child $status has completed!\n";
      }
      
      echo "Parent #{$ppid} has completed!\n";
      
      echo "\nSCRIT END AT: ", date(‘Y-m-d H:i:s‘, $start), "\n";
      echo "TOTAL TIMEEEE: " . (time() - $start)/60;
      echo "\n++++++++++++++++++++++++++++++++++++++++++++OK++++++++++++++++++++++++++++++++++++++++++++++++++\n";
      ?>
时间: 2024-08-06 03:08:37

CLI下另一种多进程实现方式----PCNTL的相关文章

ASP.NET MVC下的四种验证编程方式[续篇]

在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注ValidationAttribute特性"."让数据类型实现IValidatableObject或者IDataErrorInfo"),那么在ASP.NET MVC框架内部是如何提供针对这四种不同编程方式的支持的呢?接下来我们就来聊聊这背后的故事. 一.ModelValidator与ModelVal

ASP.NET MVC下的四种验证编程方式

原文:ASP.NET MVC下的四种验证编程方式 ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性,我们将针对参数的验证成为Model绑定.总地来说,我们可以采用4种不同的编程模式来进行针对绑定参数的验证. 目录 一.手工验证绑定的参数 二.使用ValidationAttribute特性 三.让数据类型实现IValidatableObject接口 四.让数据类型实现IDataError

ASP.NET MVC下的四种验证编程方式【转】

ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑定.总地来说,我们可以采用4种不同的编程模式来进行针对绑定参数的验证. 目录 一.手工验证绑定的参数 二.使用ValidationAttribute特性 三.让数据类型实现IValidatableObject接口 四.让数据类型实现IDataErrorInfo接口 一.手工验证绑定的参数 在 定义具

Asp.Net Core下的两种路由配置方式

与Asp.Net Mvc创建区域的时候会自动为你创建区域路由方式不同的是,Asp.Net Core下需要自己手动做一些配置,但更灵活了. 我们先创建一个区域,如下图 然后我们启动访问/Manage/Home/Index 发现是404没有找到该页面,因为我们还没有为其配置路由,下面使用两种配置区域路由的方式 1.通过配置MapRoute app.UseMvc(routes => { routes.MapRoute( name: "default", template: "

大数据形势下的三种数据融合方式:组合、整合和聚合

一. 跨行业数据合作背景 国务院副总理马凯,曾经在2015贵阳国际大数据产业博览会中提到: 融合是大数据的价值所在,应大力推动大数据与产业融合,面向工业.交通.物流.商贸.金融.电信.能源等数据量大的行业领域,开展数据开发和交易,充分挖掘大数据的商业价值,促进产业提质增效升级. 另外,<大数据时代>的作者舍恩伯格,在该书中也提到一个观点:"大数据不是随机样本而是全体数据". 无论是从国家政府部门还是领域专家都不约而同的提到数据需要融合,数据融合才有价值. 二. 为什么需要数

CentOS下的几种软件安装方式

1. rpm包 安装: rpm -ivh soft.version.rpm 更新: rpm -Uvh soft.version.rpm 卸载: 1) 查找欲卸载的软件包 rpm -qa | grep  XXX 2) 例如找到软件mysql-4.1.22-2.el4_8.4 ,执行rpm -e mysql-4.1.22-2.el4_8.4 查询软件的安装目录: rpm -ql mysql-4.1.22-2.el4_8.4 2. 以.bin结尾的安装包 安装: chmod +x ******.bin

android环境下两种md5加密方式

在平时开发过程中,MD5加密是一个比较常用的算法,最常见的使用场景就是在帐号注册时,用户输入的密码经md5加密后,传输至服务器保存起来.虽然md5加密经常用,但是md5的加密原理我还真说不上来,对md5的认知目前仅仅停留在会使用的水平,想搞清楚还是要花点时间的,这是md5加密算法的相关介绍.本文主要介绍android平台下两种md5加密方式,分别为基于java语言的md5加密及ndk环境下基于c语言的md5加密. 下面代码为基于java语言的md5加密: public String getMD5

flink on yarn模式下两种提交job方式

flink on yarn模式下两种提交job方式 https://juejin.im/post/5bf8dd7a51882507e94b8b15 https://www.cnblogs.com/asker009/p/11327533.html https://ci.apache.org/projects/flink/flink-docs-release-1.9/ops/deployment/yarn_setup.html#flink-yarn-session 原文地址:https://www.

Hive几种数据导出方式

Hive几种数据导出方式 今天我们再谈谈Hive中的几种不同的数据导出方式.可以根据导出的地方不一样,将这些方式分为三种: (1).导出到本地文件系统: (2).导出到HDFS中: (3).导出到Hive的另一个表中.为了避免单纯的文字,我将一步一步地用命令进行说明. 一.导出到本地文件系统 hive> insert overwrite local directory '/home/wyp/wyp' > select * from wyp; 这条HQL的执行需要启用Mapreduce完成,运行