其实PHP是支持并发的,只是平时很少使用而已。平时使用最多的应该是使用PHP-FMP调度php进程了吧。

但是,PHP的使用并不局限于做Web,我们完全也可以使用PHP来进行系统工具类的编程,做监控或者是运维。在使用这些方向的时候,我们可以使用到PHP的更多特性,例如并发(多进程)、socket编程等。

那么接下来就说说我遇到的PHP多进程的编程。这个多进程的使用是有一个背景的,下面模糊描述一下背景。

我需要一个监控系统,当然使用PHP语言,监控系统需要监控很多种系统指标,为了让每个监控指标之间尽量专心的去做自己的事情,就需要单独使用一个进程去监控一个指标,还有一个进程去读取配置,拿到配置之后,根据配置去启动每条进程。

那么,这就需要我所说的多进程了。

  1. 首先启动一个主进程,主进程用来读取配置信息。例如,我读取到了我需要监控5个指标
  2. 接下来主进程启动5个子进程,分别监控这5个指标。
  3. 创建好5个指标监控进程之后之后,主进程进行监听配置。
  4. 一旦配置发生改变,杀死之前的进程并重新创建进程。

相对来说比较清晰的逻辑。那么接下来我们就化简一下操作:简单的说就是一个主进程创建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。

我们可以写个程序了解一下:

 $pid = pcntl_fork();
var_dump($pid);

这个调用会输出两个值,但是我们如果直接print的只能看到一个值,也就是子进程的pid,但是使用var_dump我们就可以看到两个值,是0和子进程的pid。0这个值就是子进程返回过来的。

那么如何创建进程了解清楚之后,就可以开始创建进程了,我们需要创建5个进程,那么我就循环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为子进程的标记。我们可以通过对子进程标记来结束进程执行。所以我们可以将我们的代码修改为如下形式:

 $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解的更多相关文章

  1. php多进程编程详解

    php多进程编程 前言 php单进程存在的问题: 多核处理器未充分利用,而单处理器通常需要等待其他操作完成之后才能再继续工作. 任何现代操作系统都可在幕后执行多任务,这意味着在很短时间内,计算机可以调 ...

  2. php多进程编程相关资料(以备参考)

    进程与线程的区别 要了解二者的区别与联系,首先得对进程与线程有一个宏观上的了解. 进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位.每一个进程都 ...

  3. PHP多进程编程实例

    这篇文章主要介绍了PHP多进程编程实例,本文讲解的是在Linux下实现PHP多进程编程,需要的朋友可以参考下 羡慕火影忍者里鸣人的影分身么?没错,PHP程序是可以开动影分身的!想完成任务,又觉得一个进 ...

  4. Python多进程编程

    转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...

  5. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  6. Linux下的多进程编程

    1.进程 1.1进程的定义 <计算机操作系统>这门课对进程有这样的描述:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统 ...

  7. Android 多进程编程 15问15答!

    ps:阅读本文 需要对android 多进程编程有一定了解. 1.Android中总共有几种方式进行IPC? 答:一共有两种,一种是binder 还有一种是socket.Binder 大家用的比较多. ...

  8. Linux串口编程详解(转)

    串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...

  9. 嵌入式linux多进程编程

    嵌入式linux多进程编程 在主程序显示文本菜单.提供例如以下服务.要求每一个服务都通过生成子进程来提供. 服务包含:日历信息显示,日期信息显示,推断闰年服务,文件复制功能,数字排序功能.退出功能. ...

随机推荐

  1. BotVS开发基础—2.7 指标MA

    代码 #计算一小时 MA5均线 # 时间 2017-06-29 00:00:00 -2017-06-30 00:00:00 1小时 实盘级Tick # 平台 OCKCoin BTC def main( ...

  2. Node.js之操作文件系统(二)

    Node.js之操作文件系统(二) 1.创建与读取目录 1.1 创建目录 在fs模块中,可以使用mkdir方法创建目录,该方法的使用方法如下: fs.mkdir(path,[mode],callbca ...

  3. sdram控制2

    芯片手册要求sdram需要在64ms内刷新8K次,否则里面的数据会丢失,因此在64ms分成8192次,每次刷新充一次电,然后给两次自动刷新命令即可. /*----------------------- ...

  4. SpringBoot 注解事务声明式事务

    转载请注明: http://www.cnblogs.com/guozp/articles/7446477.html springboot 对新人来说可能上手比springmvc要快,但是对于各位从sp ...

  5. Chome——扩展程序,获取更多扩展程序报错

    修改/替换hosts文件 地址:c:/windows/system32/drivers/etc hosts:可从网上搜索下载或网盘下载(链接: http://pan.baidu.com/s/1bpu6 ...

  6. 项目管理svn

    https://nchc.dl.sourceforge.net/project/tortoisesvn/1.9.6/Application/TortoiseSVN-1.9.6.27867-x64-sv ...

  7. CountDownLatch和CyclicBarrier 特点比较

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp79   并发编程中的CountDownLatch和CyclicBarri ...

  8. iOS蓝牙交互(4.0)

    前期准备工作:查看coreBlueTooth框架,查看一些蓝牙名词:Central(中心设备).Peripheral(外围设备).advertisementData(广播数据).-RSSI: 信号强弱 ...

  9. 在Centos7x上部署docker

    docker只支持CentOS7.x系统,所以近期根据docker官网指南自己搭建了一套,供大家参考. 1.部署Centos7.x系统,查看系统版本. 2.执行 sudo yum update 更新到 ...

  10. 201521123107 《Java程序设计》第9周学习总结

    第9周作业-异常 1.本周学习总结 2.书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什 ...