PHP 进程池与轮询调度算法实现多任务的示例代码


Posted in PHP onNovember 26, 2019

phper 请了解进程调度策略,CPU 时间片,进程控制【创建,销毁,回收,进程信号】与及进程运行流程和基本的进程组,信号中断原理,以及进程之间的关系。

关于进程的更多内容可参考本人前面撸过的文章或是百度了解。

进程的通信:

匿名管道,命名管道,消息队列,内存共享,socketpair 请自行撸代码测试哦

进程的调度算法:

轮询,随机分发,计分板等策略或是搞个优先极或是队列,或是堆栈等基本的算法【自己去发挥哦】

进程池:

撸过 tcp 的话应该知道要能处理多个客户端,就得用 IO 复用技术【事件多路分发器】或是多进程以及多线程,每来一个客户端就 fork 一个进程或是线程,那样的话上下文切换成本特别高,所以咱们先创建好一组进程【进程池】,等客户端连接上来的时候,通过某种算法【我们用的轮询】来选择某个进程投递任务来干活,这样的话就不用创建又销毁来回折腾了,提升它的效率。下面是 PHP 代码版本的实现

<?php
/**
 * Created by PhpStorm.
 * User: 1655664358@qq.com
 * Date: 2019/1/12
 * Time: 16:18
 */

$flag = 1;

class process
{
 public $pid;
 public $name;
 public $file;
 public $num;
}
class instance
{
 public $processIdx;
 public $proc = [];
 public $processNum;
}
function sigHandler($sigNo)
{
 global $flag;
 $flag = 0;
 echo "信号中断处理".PHP_EOL;
}
function processPool(instance &$instance,$num)
{

 if (!$instance||$num==0){
  fprintf(STDERR,"%s","参数错误");
  return 1;
 }
 $instance->processIdx = 0;
 $instance->processNum = $num;

 pcntl_signal(SIGINT,'sigHandler');
 pcntl_signal(SIGTERM,'sigHandler');

 $process = new process();
 for ($i=1;$i<=$num;$i++){
  $instance->proc[$i] = clone $process;
  $instance->proc[$i]->file = $i;
  $instance->proc[$i]->pid = pcntl_fork();
  $instance->processIdx = $i;
  if ($instance->proc[$i]->pid<0){
   exit("进程创建失败");
  }
  else if ($instance->proc[$i]->pid>0){
   //nothing
   continue;
  }else{

   worker($instance);
  }
 }
 master($instance);
 $exitProcess= [];
 while (1){
  for ($i=1;$i<=$num;$i++){
  //非阻塞方式回收子进程
   pcntl_waitpid($instance->proc[$i]->pid,$status,WNOHANG);
   if ($status){
    $exitProcess[] = $instance->proc[$i]->pid;
    fwrite(STDOUT,"worker#".$instance->proc[$i]->pid."-".$status,30);
   }
  }
  if (count($exitProcess)==$instance->processNum){
   exit(0);
  }
  usleep(1000);

 }

}
//简单的轮询算法 自己可以用队列,随机,链表,栈链,二叉树啥的折腾
function roundRobin(&$instance,$roll)
{
 /** @var instance $instance */
 return $instance->proc[$roll%$instance->processNum+1];
}

function master(&$instance)
{

 /** @var instance $instance */
 fprintf(STDOUT,"master 进程 %d\n",$instance->processIdx);
 global $flag;
 $roll = 0;
 while ($flag){
  pcntl_signal_dispatch();
  /** @var process $process */
  $process = roundRobin($instance,$roll++);
  echo "轮询的进程:".$process->pid.PHP_EOL;
  $file = $process->file;
  posix_mkfifo($file,0666);
  $fd = fopen($file,"w");
  fwrite($fd,"hi",2);
  sleep(1);

 }
 for ($i=1;$i<=$instance->processNum;$i++){
  posix_kill($instance->proc[$i]->pid,9);
 }
 fprintf(STDOUT,"master shutdown %d\n",$instance->processIdx);
}
function getProcess(&$instance)
{
 /** @var instance $instance */
 return $instance->proc[$instance->processIdx];
}
function worker(&$instance)
{
 /** @var process $process */
 $process = getProcess($instance);
 while (1){
  $file = $process->file;
  posix_mkfifo($file,0666);
  $fd = fopen($file,"r");
  $content = fread($fd,10);
  fprintf(STDOUT,"worker#%d读取的内容:%s file=%d\n",posix_getpid(),$content,$file);
 }
 exit(0);
}

$instance = new instance();
processPool($instance,5);

效果

PHP 进程池与轮询调度算法实现多任务的示例代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php实现与erlang的二进制通讯实例解析
Jul 23 PHP
PHP常用处理静态操作类
Apr 03 PHP
PHP+ajax分页实例简析
Dec 07 PHP
Laravel与CI框架中截取字符串函数
May 08 PHP
php进行ip地址掩码运算处理的方法
Jul 11 PHP
php使用str_replace替换多维数组的实现方法分析
Jun 15 PHP
PHP-X系列教程之内置函数的使用示例
Oct 16 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
Apr 21 PHP
PHP+Ajax实现上传文件进度条动态显示进度功能
Jun 04 PHP
Laravel用户授权系统的使用方法示例
Sep 16 PHP
PHP结合Ffmpeg快速搭建流媒体服务的实践记录
Oct 31 PHP
Ubuntu 16.04中Laravel5.4升级到5.6的步骤
Dec 07 PHP
PHP PDO和消息队列的个人理解与应用实例分析
Nov 25 #PHP
Laravel Eloquent分表方法并使用模型关联的实现
Nov 25 #PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
Nov 25 #PHP
使用Git实现Laravel项目的自动化部署
Nov 24 #PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
Nov 24 #PHP
laravel框架中视图的基本使用方法分析
Nov 23 #PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 23 #PHP
You might like
跟我学Laravel之请求(Request)的生命周期
2014/10/15 PHP
PHP定时执行任务实现方法详解(Timer)
2015/07/30 PHP
PHP中header用法小结
2016/05/23 PHP
PHP获取指定日期是星期几的实现方法
2016/11/30 PHP
25个好玩的JavaScript小游戏分享
2011/04/22 Javascript
浅谈jQuery页面的滚动位置scrollTop、scrollLeft
2015/05/19 Javascript
JavaScript中字符串与Unicode编码互相转换的实现方法
2015/12/18 Javascript
JS组件Bootstrap Table使用方法详解
2016/02/02 Javascript
JS函数多个参数默认值指定方法分析
2016/11/28 Javascript
Bootstrap Table使用整理(二)
2017/06/09 Javascript
浅谈Webpack 持久化缓存实践
2018/03/22 Javascript
Javascript迭代、递推、穷举、递归常用算法实例讲解
2019/02/01 Javascript
vue移动端城市三级联动组件使用详解
2019/07/26 Javascript
Vue+Koa2 打包后进行线上部署的教程详解
2019/07/31 Javascript
[37:02]OG vs INfamous 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python 字符串操作方法大全
2014/03/11 Python
用python实现面向对像的ASP程序实例
2014/11/10 Python
python中异常捕获方法详解
2017/03/03 Python
Python 实现数据库更新脚本的生成方法
2017/07/09 Python
Python实现嵌套列表去重方法示例
2017/12/28 Python
Python中sort和sorted函数代码解析
2018/01/25 Python
Python 实现字符串中指定位置插入一个字符
2018/05/02 Python
Python设置在shell脚本中自动补全功能的方法
2018/06/25 Python
利用Python代码实现一键抠背景功能
2019/12/29 Python
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
2013/01/09 HTML / CSS
全球速卖通西班牙站:AliExpress西班牙
2017/10/30 全球购物
爱尔兰灯和灯具网上商店:Lights.ie
2018/03/26 全球购物
C语言基础笔试题
2013/04/27 面试题
《长城》教学反思
2014/02/14 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
学习焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
小学班主任工作总结2015
2015/04/07 职场文书
2016十一国庆节感言
2015/12/09 职场文书
vue中data改变后让视图同步更新的方法
2021/03/29 Vue.js
Win11应用商店打开闪退怎么解决? win11应用商店打不开的多种解决办法
2022/04/05 数码科技
讲解MySQL增删改操作
2022/05/06 MySQL