PHP多进程编之pcntl_fork的实例详解
PHP多进程编之pcntl_fork的实例详解
其实PHP是支持并发的,只是平时很少使用而已。平时使用最多的应该是使用PHP-FMP调度php进程了吧。
但是,PHP的使用并不局限于做Web,我们完全也可以使用PHP来进行系统工具类的编程,做监控或者是运维。在使用这些方向的时候,我们可以使用到PHP的更多特性,例如并发(多进程)、socket编程等。
那么接下来就说说我遇到的PHP多进程的编程。这个多进程的使用是有一个背景的,下面模糊描述一下背景。
我需要一个监控系统,当然使用PHP语言,监控系统需要监控很多种系统指标,为了让每个监控指标之间尽量专心的去做自己的事情,就需要单独使用一个进程去监控一个指标,还有一个进程去读取配置,拿到配置之后,根据配置去启动每条进程。
那么,这就需要我所说的多进程了。
- 首先启动一个主进程,主进程用来读取配置信息。例如,我读取到了我需要监控5个指标
- 接下来主进程启动5个子进程,分别监控这5个指标。
- 创建好5个指标监控进程之后之后,主进程进行监听配置。
- 一旦配置发生改变,杀死之前的进程并重新创建进程。
相对来说比较清晰的逻辑。那么接下来我们就化简一下操作:简单的说就是一个主进程创建5个子进程。
首先,创建进程在需要使用php的一个函数pcntl_fork(),这个函数可能有的同学不太熟,不过接触过Linux C变成的人都知道Linux下有个叫fork()的函数,用来创建子进程。这个函数和Linux下这个函数是一个意思。需要注意的是,这个函数在Linux下才能使用,而且需要安装pcntl的扩展。
对于这个函数怎么使用,我们可以查阅官方文档:http://php.net/manual/zh/function.pcntl-fork.php
官方文档是这样说的:
pcntl_fork()函数创建一个子进程,这个子进程仅PID(进程号) 和PPID(父进程号)与其父进程不同。fork怎样在您的系统工作的详细信息请查阅您的系统 的fork(2)手册。
成功时,在父进程执行线程内返回产生的子进程的PID,在子进程执行线程内返回0。失败时,在 父进程上下文返回-1,不会创建子进程,并且会引发一个PHP错误。
这样就可以创建一个子进程了,子进程创建成功以后会执行pcntl_fork()之后的方法。那么对于这个函数的返回值我们如何理解呢?
是这样的,我们调用函数创建进程的时候,函数执行时有时间的,而新的进程刚好是在函数执行开始和结束之间创建出来的,这样,新的进程也执行了这个函数,所以函数也需要有返回值。那么对于该函数一次执行之后,父进程和子进程都会受到该函数的返回值,由于父进程创建了子进程,而子进程并没有创建新的进程,所以子进程对于这个函数的返回结果是没有的,所以就给他赋了一个0。而父进程创建了子进程,子进程是存在pid的,所以就得到了那个进程的pid。
我们可以写个程序了解一下:
1
2
|
$pid = pcntl_fork(); var_dump( $pid ); |
这个调用会输出两个值,但是我们如果直接print的只能看到一个值,也就是子进程的pid,但是使用var_dump我们就可以看到两个值,是0和子进程的pid。0这个值就是子进程返回过来的。
那么如何创建进程了解清楚之后,就可以开始创建进程了,我们需要创建5个进程,那么我就循环5次创建进程。得到如下代码:
1
2
3
4
5
|
$i =0; while ( $i !=5){ $pid = pcntl_fork(); echo $pid . "---------hahah" . $i ++.PHP_EOL; } |
这样就写好了,那么运行一下吧。啊?发现不是5个进程啊,发现有好多个进程,而且最后一个hahah4这个输出有32个,为什么是32呢?我们算一算。2^5=32,为什么最后的线程数以指数增长了呢?
想发现这个并不难,因为我们之后的每一条都执行了while循环,到最后成了进程的指数增长——也就是说fork的时候把while循环也带了进去。但是我们只是要5个进程而已。怎么办呢?
通过之前对函数的研究可以看到,子进程中会返回一个为0的值,那么我们就可以知道,0为子进程的标记。我们可以通过对子进程标记来结束进程执行。所以我们可以将我们的代码修改为如下形式:
1
2
3
4
5
6
7
8
9
|
$i =0; while ( $i !=5){ $pid = pcntl_fork(); echo $pid . "---------hahah" . $i ++.PHP_EOL; if ( $pid == 0) { echo "子进程" .PHP_EOL; return ; } } |
因为0其实是对子进程的标记,那么pid这个变量在子进程里实际上是0的,所以当发现pid的值为0的时候,我们就可以断定我们当前进程为一个子进程,不需要在让他执行while并创建子进程的子进程了,所以在执行完我们的内容之后就return或者exit退出这个执行就好了。这样就能保证我们执行创建了5个进程而不是32个了。
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持
PHP多进程编之pcntl_fork的实例详解的更多相关文章
- 【python3+request】python3+requests接口自动化测试框架实例详解教程
转自:https://my.oschina.net/u/3041656/blog/820023 [python3+request]python3+requests接口自动化测试框架实例详解教程 前段时 ...
- JS hashMap实例详解
链接:http://www.jb51.net/article/85111.htm JS hashMap实例详解 作者:囧侠 字体:[增加 减小] 类型:转载 时间:2016-05-26我要评论 这篇文 ...
- python+requests接口自动化测试框架实例详解
python+requests接口自动化测试框架实例详解 转自https://my.oschina.net/u/3041656/blog/820023 摘要: python + requests实 ...
- Java中JSON字符串与java对象的互换实例详解
这篇文章主要介绍了在java中,JSON字符串与java对象的相互转换实例详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JS ...
- jQuery对html元素的取值与赋值实例详解
jQuery对html元素的取值与赋值实例详解 转载 2015-12-18 作者:欢欢 我要评论 这篇文章主要介绍了jQuery对html元素的取值与赋值,较为详细的分析了jQuery针对常 ...
- Java中JSON字符串与java对象的互换实例详解(转)
http://www.jb51.net/article/90914.htm 在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JSON等,JSON作为一个轻量级的数据格式比xml效率要 ...
- Linux备份数据库,mysqldump命令实例详解
mysqldump是mysql数据库中备份工具,用于将MYSQL服务器中的数据库以标准的sql语言的方式导出,并保存到文件中. 语法: mysqldump (选项) 选项: --add-drop-ta ...
- linux基础-磁盘阵列(RAID)实例详解
磁盘阵列(RAID)实例详解 raid技术分类 软raid技术 硬raid技术 Raid和lvm的区别 为什么选择用raid RAID详解 RAID-0 RAID-1 RAID-5 Raid-10 R ...
- Cocos2d-x 3.X手游开发实例详解
Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048.卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰 ...
随机推荐
- ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO) ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: YES)
windows下,以上两个错误的解决方法 工具/原料 windows 8 MySql 方法/步骤 找到配置文件my.ini ,然后将其打开,可以选择用记事本打开 打开后,搜索mysq ...
- Idea设置快捷键以及修改Eclipse的debug快捷键
Idea强大不多说了,用久了都可以习惯,但是感觉Idea的debug真是不如eclipse好用,Idea的快捷键都是组合键,用着繁琐.两种方法可以设置eclipse的快捷键: 1:直接全局都使用ecl ...
- 敌兵布阵 HDU - 1166 (树状数组模板题,线段树模板题)
思路:就是树状数组的模板题,利用的就是单点更新和区间求和是树状数组的强项时间复杂度为m*log(n) 没想到自己以前把这道题当线段树的单点更新刷了. 树状数组: #include<iostrea ...
- linux 的常用命令---------第十一阶段
软件管理rpm.yum 在 windows 与 linux 之间 实现小文件传输(仅支持在 X shell 中完成文件传输,虚拟机中不可实现): # yum install lrzsz -y ...
- ECS简述
一.查看ECS实例 使用场景 •实例的日常维护 •实例运行状态和详细信息的查看 二.启动ECS实例 使用场景 •实例停止运行之后的再次启动 三.停止.重启ECS实例 使用场景 •实例运行的服务暂停时停 ...
- 如何使用zabbix初级监控
如何用zabbix监控(初步使用)? 前提:必须启动mysql 和zabbix目录下的sbin中的zabbix_agentd zabbix_server,还有nginx以及php否则会报错,因为zab ...
- QT中PRO文件写法的详细介绍
学习Qt时,发现有些知识看了不经常用就忘了,以下是书本上写的一些关于qmake的相关知识,自己看后,打算把一些经常用到的记下来,整理整理. Qt程序一般使用Qt提供的qmake工具来编译. qmake ...
- 20175105 2018-2019-2 《Java程序设计》第八周学习总结
20175105 2018-2019-2 <Java程序设计>第八周学习总结 教材学习内容总结 第十五章主要内容有:泛型.链表.堆栈.散列映射.树集以及树映射. 泛型:可以使用class名 ...
- Objective-C Mach-O文件格式深入理解
Mach-O(Mach Object),是一种基于Mach内核的文件格式,苹果很多文件都采用这种格式,最常见的就是可执行文件和动态库. 当然,还有.o的目标文件..a和.framework的静态库以及 ...
- JavaScript设计模式 - 订阅发布模式(观察者模式)
var Event = (function() { var global = this, Event, _default = 'default'; Event = function() { var _ ...