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 相关文章推荐
COM in PHP (winows only)
Oct 09 PHP
简化php模板页面中分页代码的解析
Feb 06 PHP
php.ini 配置文件的深入解析
Jun 17 PHP
关于file_get_contents返回为空或函数不可用的解决方案
Jun 24 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
Nov 28 PHP
PHP清除字符串中所有无用标签的方法
Dec 01 PHP
使用PHP实现阻止用户上传成人照片或者裸照
Dec 25 PHP
ThinkPHP 404页面的设置方法
Jan 14 PHP
[原创]php获取数组中键值最大数组项的索引值
Mar 17 PHP
PHP和Mysql中转UTF8编码问题汇总
Oct 10 PHP
Yii控制器中filter过滤器用法分析
Jul 15 PHP
php实现用户登陆简单实例
Apr 04 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
PHP中实现图片的锐化
2006/10/09 PHP
玩转虚拟域名◎+ .
2006/10/09 PHP
phpexcel导出excel的颜色和网页中的颜色显示不一致
2012/12/11 PHP
PHP 之 写时复制介绍(Copy On Write)
2014/05/13 PHP
PHPExcel读取EXCEL中的图片并保存到本地的方法
2015/02/14 PHP
Javascript技术技巧大全(五)
2007/01/22 Javascript
如何用js控制css中的float的代码
2007/08/16 Javascript
JS array 数组详解
2009/03/22 Javascript
利用jQuery插件扩展识别浏览器内核与外壳的类型和版本的实现代码
2011/10/22 Javascript
利用javascript解决图片缩放及其优化的代码
2012/05/23 Javascript
Jquery通过Ajax方式来提交Form表单的具体实现
2013/11/07 Javascript
JavaScrip实现PHP print_r的数功能(三种方法)
2013/11/12 Javascript
node.js中的fs.lstat方法使用说明
2014/12/16 Javascript
vue实现ajax滚动下拉加载,同时具有loading效果(推荐)
2017/01/11 Javascript
如何把vuejs打包出来的文件整合到springboot里
2018/07/26 Javascript
Electron实现应用打包、自动升级过程解析
2020/07/07 Javascript
python利用有道翻译实现&quot;语言翻译器&quot;的功能实例
2017/11/14 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
解决python "No module named pip" 的问题
2018/10/13 Python
使用python将时间转换为指定的格式方法
2018/11/12 Python
Python对接六大主流数据库(只需三步)
2019/07/31 Python
命令行运行Python脚本时传入参数的三种方式详解
2019/10/11 Python
Python中的list与tuple集合区别解析
2019/10/12 Python
Django中文件上传和文件访问微项目的方法
2020/04/27 Python
keras读取h5文件load_weights、load代码操作
2020/06/12 Python
python用什么编辑器进行项目开发
2020/06/17 Python
python db类用法说明
2020/07/07 Python
HTML5使用ApplicationCache接口实现离线缓存技术解决离线难题
2012/12/13 HTML / CSS
AmazeUI 点击元素显示全屏的实现
2020/08/25 HTML / CSS
美国Jeep配件购物网站:Morris 4×4 Center
2019/05/01 全球购物
交通法规咨询中心工作职责
2013/11/27 职场文书
中学生班主任评语
2014/01/30 职场文书
需求分析说明书
2014/05/09 职场文书
2014年小学语文工作总结
2014/12/20 职场文书
python单向链表实例详解
2022/05/25 Python
element tree树形组件回显数据问题解决
2022/08/14 Javascript