php是一门单进程弱类型的语言,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,多进程的作用优点大家可以去网上了解,PHP实现多进程在实际项目中意义也是不容小觑的。比如:日常任务中,有时需要通过php脚本执行一些日志分析,队列处理等任务,当数据量比较大时,可以使用多进程来处理。

要实现PHP的多进程,需要用到函数pcntl_fork,那么就需要开启扩展 pcntl和 posix,在上一篇文章已经有安装方法。

入门须知

  • 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
  • 僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
  • 僵尸进程危害:如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。
  • 已经产生的僵尸进程,解决方法:kill掉父进程,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源。

鸟哥语录(多进程优点)http://www.laruence.com/2009/06/11/930.html

  • 使用多进程, 子进程结束以后, 内核会负责回收资源
  • 使用多进程,子进程异常退出不会导致整个进程Thread退出. 父进程还有机会重建流程.
  • 一个常驻主进程, 只负责任务分发, 逻辑更清楚.

切记!切记!切记!

  • PHP多进程一般应用在PHP_CLI命令行中执行php脚本,不要在web访问时使用。
  • 通过pcntl_XXX系列函数使用多进程功能。注意:pcntl_XXX只能运行在php CLI(命令行)环境下,在web服务器环境下,会出现无法预期的结果,请慎用!
  • 鸟哥提醒:也就是说, 打消你在PHP Web开发中使用多进程的念头吧!

创建子进程(pcntl_fork)

pcntl_fork() — 在当前进程当前位置产生分支(子进程)。此函数创建了一个新的子进程后,子进程会继承父进程当前的上下文,和父进程一样从pcntl_fork()函数处继续向下执行,只是获取到的pcntl_fork()的返回值不同,我们便能从判断返回值来区分父进程和子进程,分配父进程和子进程去做不同的逻辑处理。
pcntl_fork()函数成功执行时会在父进程返回子进程的进程id(pid),因为系统的初始进程init进程的pid为1,后来产生进程的pid都会大于此进程,所以我们可以通过判断pcntl_fork()的返回值大于1来确实当前进程是父进程;
而在子进程中,此函数的返回值会是固定值0,我们也可以通过判断pcntl_fork()的返回值为0来确定子进程;
而pcntl_fork()函数在执行失败时,会在父进程返回-1,当然也不会有子进程产生。

简单demo

<?php
$ppid = posix_getpid();
$pid = pcntl_fork();
if ($pid == -) {
echo 'fork子进程失败!';
} elseif ($pid > ) {
echo "我是父进程,我的进程id是{$ppid}.";
echo "\r\n";
sleep(); // 保持20秒,确保能被ps查到
}else{
$cpid = posix_getpid();
echo "我是{$ppid}的子进程,我的进程id是{$cpid}.";
echo "\r\n";
sleep(); // 保持20秒,确保能被ps查到
}
# php fork.php   //centos下执行命令
我是父进程,我的进程id是7625.
我是7625的子进程,我的进程id是7626.
# ps aux | grep fork.php  //centos下20秒内执行命令
root 0.0 0.6 pts/ S+ : : php fork.php
root 0.0 0.4 pts/ S+ : : php fork.php
root 7.0 0.0 pts/ S+ : : grep fork.php

posix_getpid()函数作用是:获取当前进程的pid;

进一步说明

上边的代码如果创建子进程成功的话,系统就有了2个进程,一个为父进程,一个为子进程,子进程的id号为$pid。在系统运行到$pid = pcntl_fork();时,在这个地方进行分支,父子进程各自开始运行各自的程序代码。代码的运行结果是父进程那块代码 和子进程的代码都走了,很奇怪吧,为什么一个elseif和else互斥的代码中,都输出了结果?其实是像上边所说的,代码在pcntl_fork时,一个父进程运行父进程那块代码,一个子进程运行了子进程那块代码。在代码结果上就显示了“我是父进程....”和"我是子进程..."。至于谁先谁后的问题,这得要看系统资源的分配了。

PHP多进程学习(一)__来初步了解一下PHP多进程及简单demo的更多相关文章

  1. PHP多进程学习(三)__代码案例来了解父进程与子进程的执行顺序

    pcntl_fork创建子进程成功的话,系统就有了2个进程,一个为父进程,一个为子进程,父进程和子进程都继续向下执行,子进程的id号为$pid(父进程会获取子进程的$pid也就是$pid不为0,而子进 ...

  2. Caffe学习使用__运行caffe自带的两个简单例子

    为了程序的简洁,在caffe中是不带练习数据的,因此需要自己去下载.但在caffe根目录下的data文件夹里,作者已经为我们编写好了下载数据的脚本文件,我们只需要联网,运行这些脚本文件就行了. 注意: ...

  3. PHP多进程学习(二)__fork起多个子进程,父进程的阻塞与非阻塞

    先简单来了解一下多进程 [来初步了解一下PHP多进程及简单demo] php的多进程是不是可以无限制的fork子进程?fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的 ...

  4. elasticsearch学习笔记——安装,初步使用

    前言 久仰elasticsearch大名,近年来,fackbook,baidu等大型网站的搜索功能均开始采用elasticsearch,足见其在处理大数据和高并发搜索中的卓越性能.不少其他网站也开始将 ...

  5. MySQL学习(一): MySQL的初步操作与命令

    启动与关闭: 用管理员身份运行cmd 启动:net start mysql57 其中mysql57是我的MySQL名称,版本不同名称可能不一样 关闭:net stop mysql57 与上面同理 登录 ...

  6. 【Android学习】Service&Boradcast初步

    Service初步 掌握Service概念 掌握Service分类 Service开发能力具备 了解Service和intentService类的区别 重点难点 StartService和BoundS ...

  7. Makefile学习(一)----初步理解

    一.我对makefile的理解: 经过一段时间对makefile的学习,我理解的makefile就是将程序员手动编译源文件的过程用一个脚本执行,这对于小型项目来说,程序员手动执行和用makefile来 ...

  8. java8学习之Lambda表达式初步与函数式接口

    对于Java8其实相比之前的的版本增加的内容是相当多的,其中有相当一大块的内容是关于Lambda表达式与Stream API,而这两部分是紧密结合而不能将其拆开来对待的,但是是可以单独使用的,所以从学 ...

  9. 0032 Java学习笔记-类加载机制-初步

    JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...

随机推荐

  1. php学习十三:其他关键字

    在php中,其实不止在php中,在其他语言中我们也会常常接触到一些关键字,整理了一下php当中的一下关键字,可能有些不全,希望大家指出来,多多交流,一起进步. 1.final 特性:1.使用final ...

  2. ATL字符宏使用以及代码测试

    // ATL_Convert.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #incl ...

  3. c/c++设置图片为透明图

    在绘制图片的时候先把源位图填充背景设置为白色 例如:m_bufferpicture.FillSolidRect(0,0,m_nWidth,m_nHeight,RGB(255,255,255));//这 ...

  4. 《C++ Primer Plus》15.5 类型转换运算符 学习笔记

    C++相对C更严格地限制允许的类型转换,并添加4个类型转换运算符,是转换过程更规范:* dynamic_cast:* const_cast:* static_cast:* reinterpret_ca ...

  5. Android App签名打包 与 SDK开发文档

    Android App签名打包签名的意义1.为了保证每个程序开发者的合法权益2.放置部分人通过使用相同的Package Name来混淆替换已经安装的程序,从而出现一些恶意篡改3.保证我们每次发布的版本 ...

  6. PHP之命名空间

    前面的话 从广义上来说,命名空间是一种封装事物的方法.在很多地方都可以见到这种抽象概念.例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色.这个原理应用到程序设计 ...

  7. C++模板实战6:迭代器

    1 迭代器的类型: 输入迭代器 .前向迭代器.双向迭代器.跳转迭代器以及输出迭代器.这五种迭代器的限制条件从左至右越来越强. 2 输入迭代器需满足的条件: X u(a); X可复制构造 u=a; 可赋 ...

  8. Android内存优化总结【整理】

    http://blog.csdn.net/tiantangrenjian/article/details/39182293 [前段时间接到任务着手进行app的内存优化,从各种各样的渠道搜索相关资料,最 ...

  9. JQuery 用法总结

    1.隐藏与显示,用于div等等 //隐藏id=myTab下的所有li标签 $("#myTab li").hide(); //动画隐藏,1秒内隐藏该对象 $(); //显示class ...

  10. UINavigationController和UITabBarController

    UINavigationController和UITabBarController 目录 概述 UINavigationController UITabBarController 实用功能 待解决 概 ...