PHP 进程池与轮询调度算法实现多任务的示例代码
发布:smiling 来源: PHP粉丝网 添加日期:2022-01-24 14:07:53 浏览: 评论:0
这篇文章主要介绍了PHP 进程池与轮询调度算法实现多任务的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
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);
效果
Tags: PHP进程池 PHP轮询调度
- 上一篇:PHP PDO和消息队列的个人理解与应用实例分析
- 下一篇:最后一页
相关文章
- ·swoole_process实现进程池的方法示例(2021-11-01)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)