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 相关文章推荐
在字符串中把网址改成超级链接
Oct 09 PHP
PHP获取网站域名和地址的代码
Aug 17 PHP
php mysql Errcode: 28 终极解决方法
Jul 01 PHP
用PHP实现Ftp用户的在线管理
Feb 16 PHP
微信扫描二维码登录网站代码示例
Dec 30 PHP
初识laravel5
Mar 02 PHP
php抽奖概率算法(刮刮卡,大转盘)
Apr 17 PHP
在php7中MongoDB实现模糊查询的方法详解
May 03 PHP
Swoole4.4协程抢占式调度器详解
May 23 PHP
关于laravel 数据库迁移中integer类型是无法指定长度的问题
Oct 09 PHP
Laravel validate error处理,ajax,json示例
Oct 25 PHP
php生成随机数/生成随机字符串的方法小结【5种方法】
May 27 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学习笔记之三 数据库基本操作
2011/01/17 PHP
仿Aspnetpager的一个PHP分页类代码 附源码下载
2012/10/08 PHP
PHP笔记之:日期函数的使用介绍
2013/04/24 PHP
PHP-Java-Bridge使用笔记
2014/09/22 PHP
微信公众号判断用户是否已关注php代码解析
2016/06/24 PHP
php 从指定数字中获取随机组合的简单方法(推荐)
2017/04/05 PHP
php删除数组指定元素实现代码
2017/05/03 PHP
Aster vs KG BO3 第一场2.19
2021/03/10 DOTA
javascript动态加载三
2012/08/22 Javascript
JavaScript地图拖动功能SpryMap的简单实现
2013/07/17 Javascript
JS+CSS实现鼠标滑过时动态翻滚的导航条效果
2015/09/24 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
基于JS代码实现图片在页面中旋转效果
2016/06/16 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
2016/06/20 Javascript
AngularJS入门教程之服务(Service)
2016/07/27 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
2016/12/29 Javascript
使用原生js+canvas实现模拟心电图的实例
2017/09/20 Javascript
NodeJS实现自定义流的方法
2018/08/01 NodeJs
详解微信小程序的 request 封装示例
2018/08/21 Javascript
解决vue select当前value没有更新到vue对象属性的问题
2018/08/30 Javascript
Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解
2019/08/26 Javascript
[54:25]Ti4 循环赛第三日LGD vs MOUZ
2014/07/12 DOTA
[46:20]TFT vs Secret Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
python装饰器使用方法实例
2013/11/21 Python
跟老齐学Python之通过Python连接数据库
2014/10/28 Python
Python运算符重载详解及实例代码
2017/03/07 Python
python 输出上个月的月末日期实例
2018/04/11 Python
python元组拆包实现方法
2021/02/28 Python
台湾饭店和机票预订网站:Expedia台湾
2016/08/05 全球购物
Lookfantastic西班牙官网:英国知名美妆购物网站
2018/06/13 全球购物
智能钱包:Ekster
2019/11/21 全球购物
波兰家居饰品和厨房配件网上商店:Maleomi
2020/12/15 全球购物
干部行政关系介绍信
2014/01/17 职场文书
计算机实训报告总结
2014/11/05 职场文书
2014年民警工作总结
2014/11/25 职场文书
三好学生竞选稿
2015/11/21 职场文书