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 数组教程 定义数组
Oct 23 PHP
Linux下将excel数据导入到mssql数据库中的方法
Feb 08 PHP
php过滤html中的其他网站链接的方法(域名白名单功能)
Apr 24 PHP
PHP常用编译参数中文说明
Sep 27 PHP
PHP使用DirectoryIterator显示下拉文件列表的方法
Mar 13 PHP
php eval函数一句话木马代码
May 21 PHP
php计算整个mysql数据库大小的方法
Jun 19 PHP
jQuery+PHP发布的内容进行无刷新分页(Fckeditor)
Oct 22 PHP
Thinkphp5结合layer弹窗定制操作结果页面
Jul 07 PHP
PHP使用PDO创建MySQL数据库、表及插入多条数据操作示例
May 30 PHP
php使用fputcsv实现大数据的导出操作详解
Feb 27 PHP
Laravel统一错误处理为JSON的方法介绍
Oct 18 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/11/25 PHP
用PHP制作的意见反馈表源码
2007/03/11 PHP
PHP中图片等比缩放的实例
2013/03/24 PHP
如何使用“PHP” 彩蛋进行敏感信息获取
2013/08/07 PHP
php设计模式之单例模式实例分析
2015/02/25 PHP
10款PHP开源商城系统汇总介绍
2015/07/23 PHP
php进程间通讯实例分析
2016/07/11 PHP
iOS+PHP注册登录系统 PHP部分(上)
2016/12/26 PHP
js 方法实现返回多个数据的代码
2009/04/30 Javascript
Juqery Html(),append()等方法的Bug解决方法
2010/12/13 Javascript
很棒的学习jQuery的12个网站推荐
2011/04/28 Javascript
JS对HTML标签select的获取、添加、删除操作
2013/10/17 Javascript
jquery简单的弹出层浮动层代码
2015/04/27 Javascript
jQuery实现向下滑出的平滑下拉菜单效果
2015/08/21 Javascript
jquery实现简单实用的弹出层效果代码
2015/10/15 Javascript
快速学习AngularJs HTTP响应拦截器
2015/12/31 Javascript
JavaScript基础语法之js表达式
2016/06/07 Javascript
js跨域资源共享 基础篇
2016/07/02 Javascript
webpack开发跨域问题解决办法
2017/08/03 Javascript
解决ie img标签内存泄漏的问题
2017/10/13 Javascript
利用vue + element实现表格分页和前端搜索的方法
2017/12/25 Javascript
Angular5中状态管理的实现
2018/09/03 Javascript
vue.draggable实现表格拖拽排序效果
2018/12/01 Javascript
小程序自定义日历效果
2018/12/29 Javascript
如何在Angular8.0下使用ngx-translate进行国际化配置
2019/07/24 Javascript
Python+pyftpdlib实现局域网文件互传
2020/08/24 Python
python判断元素是否存在的实例方法
2020/09/24 Python
canvas烟花特效锦集
2018/01/17 HTML / CSS
Fox Racing官方网站:越野摩托车和山地自行车装备和服装
2019/12/23 全球购物
畜牧兽医本科生个人的自我评价
2013/10/11 职场文书
办公室前台岗位职责范本
2013/12/10 职场文书
经典大学生求职信范文
2014/01/06 职场文书
人事主管岗位职责
2015/02/04 职场文书
失恋33天观后感
2015/06/11 职场文书
付款证明模板
2015/06/19 职场文书
毕业生自荐求职信书写的技巧
2019/08/26 职场文书