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 09 PHP
用windows下编译过的eAccelerator for PHP 5.1.6实现php加速的使用方法
Sep 30 PHP
php数据库配置文件一般做法分享
Jul 07 PHP
php 深入理解strtotime函数的使用详解
May 23 PHP
php cURL和Rolling cURL并发方式比较
Oct 30 PHP
PHP缓存机制Output Control详解
Jul 14 PHP
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
Nov 16 PHP
PHP Ajax JavaScript Json获取天气信息实现代码
Aug 17 PHP
关于php支持的协议与封装协议总结(推荐)
Nov 17 PHP
PHP的mysqli_rollback()函数讲解
Jan 23 PHP
php+Ajax处理xml与json格式数据的方法示例
Mar 04 PHP
PHP常用字符串函数用法实例总结
Jun 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
盘点被央视点名过的日本动画电影 一部比一部强
2020/03/08 日漫
PHP安装全攻略:APACHE
2006/10/09 PHP
模拟flock实现文件锁定
2007/02/14 PHP
PHP在字符串中查找指定字符串并删除的代码
2008/10/02 PHP
php中关于codeigniter的xmlrpc的类在进行数据交换时的类型问题
2011/07/03 PHP
PHP实现的MD5结合RSA签名算法实例
2017/10/07 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
PHP日期和时间函数的使用示例详解
2020/08/06 PHP
Aptana调试javascript图解教程
2009/11/30 Javascript
jQuery示例收集
2010/11/05 Javascript
jquery post方式传递多个参数值后台以数组的方式进行接收
2013/01/11 Javascript
javascript与cookie 的问题详解
2013/11/11 Javascript
String.prototype实现的一些javascript函数介绍
2013/11/22 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
JS模拟按钮点击功能的方法
2015/12/22 Javascript
Javascript实现鼠标框选操作  不是点击选取
2016/04/14 Javascript
Vue2.X 通过AJAX动态更新数据
2018/07/17 Javascript
vue语法自动转typescript(解放双手)
2019/09/18 Javascript
JS实现滚动条触底加载更多
2019/09/19 Javascript
JavaScript实现手风琴效果
2021/02/18 Javascript
探寻python多线程ctrl+c退出问题解决方案
2014/10/23 Python
以Flask为例讲解Python的框架的使用方法
2015/04/29 Python
深入解析Python设计模式编程中建造者模式的使用
2016/03/02 Python
Python使用openpyxl读写excel文件的方法
2017/06/30 Python
python监控linux内存并写入mongodb(推荐)
2017/09/11 Python
Python进阶:生成器 懒人版本的迭代器详解
2019/06/29 Python
Python使用lambda表达式对字典排序操作示例
2019/07/25 Python
根据tensor的名字获取变量的值方式
2020/01/04 Python
基于FME使用Python过程图解
2020/05/13 Python
Python字符串split及rsplit方法原理详解
2020/06/29 Python
英国领先的独立时装店:Van Mildert
2019/10/28 全球购物
代理商会议邀请函
2014/01/27 职场文书
护理专科毕业自荐信范文
2014/04/21 职场文书
管理建议书范文
2014/05/13 职场文书
奶茶店的创业计划书该怎么写?
2019/07/15 职场文书
git stash(储藏)的用法总结
2022/06/25 Servers