Linux系统中,进程的执行模式划分为用户模式内核模式,当进程运行于用户空间时属于用户模式,
如果在用户程序运行过程中出现系统调用或者发生中断事件,就要运行操作系统(即核心)程序,进程的运行模式就变为内核模式
在该模式下运行的进程可以执行机器特权指令,而且该进程的运行不受用户的干预。

pcntl_fork()函数创建一个子进程,这个子进程仅PID(进程号) 和PPID(父进程号)与其父进程不同
成功时,在父进程执行线程内返回产生的子进程的PID,在子进程执行线程内返回0。失败时,在 父进程上下文返回-1,不会创建子进程

调用函数创建进程的时候,函数执行是有时间的,而新的进程刚好是在函数执行开始和结束之间创建出来的,
这样,新的进程也执行了这个函数,所以函数也需要有返回值。
那么对于该函数一次执行之后,父进程和子进程都会受到该函数的返回值
由于父进程创建了子进程,而子进程并没有创建新的进程,所以子进程对于这个函数的返回结果是没有的,
所以就给他赋了一个0
而父进程创建了子进程,子进程是存在pid的,所以就得到了那个进程的pid

下面不考虑进程创建失败的情况

<?php
echo "###\n";
echo posix_getpid();
echo "\n------------\n";
$i=0;
while($i<2){
$pid = pcntl_fork();
echo "now pid:".sprintf("%5d",posix_getpid())."--->父pid:".sprintf("%5d",posix_getppid())."--->fork_return:".sprintf("%5d",$pid)."----->p_".$i++.PHP_EOL;
}
exit;

输出和简析

###
15280
------------
now pid:15280--->父pid:14413--->fork_return:15281----->p_0
now pid:15281--->父pid:15280--->fork_return: 0----->p_0
now pid:15280--->父pid:14413--->fork_return:15282----->p_1
now pid:15282--->父pid:15280--->fork_return: 0----->p_1
now pid:15281--->父pid:15280--->fork_return:15283----->p_1
now pid:15283--->父pid:15281--->fork_return: 0----->p_1
发现打印了4次p_1
分析
当前pid 15280
i=0时记为step1
15280分裂成15280(pcntl_fork()返回15281)
15280分裂成15281(pcntl_fork()返回0)
i=1时记为step2
step1的15280分裂成15280(pcntl_fork()返回15282)
step1的15280分裂成15282(pcntl_fork()返回0) step1的15281分裂成15281(pcntl_fork()返回15283)
step1的15281分裂成15283(pcntl_fork()返回0)

返回0的表示创建了新的子进程在子进程的返回
现在我们只要2个进程(更多也原理一样)
如果使用循环
比如我们要5个进程

<?php
echo "###\n";
echo posix_getpid();
echo "\n------------\n";
$i=0;
while($i<5){
$pid = pcntl_fork();
echo "now pid:".sprintf("%5d",posix_getpid())."--->父pid:".sprintf("%5d",posix_getppid())."--->fork_return:".sprintf("%5d",$pid)."----->p_".$i++.PHP_EOL;
//子进程里的返回,不再进行while的pcntl_fork
if($pid == 0){
echo posix_getpid()." is a child procress!\n";
return '';
}
}
exit;
?>

输出

###
15262
------------
now pid:15262--->父pid:14413--->fork_return:15263----->p_0
now pid:15263--->父pid:15262--->fork_return: 0----->p_0
15263 is a child procress!
now pid:15262--->父pid:14413--->fork_return:15264----->p_1
now pid:15264--->父pid:15262--->fork_return: 0----->p_1
15264 is a child procress!
now pid:15262--->父pid:14413--->fork_return:15265----->p_2
now pid:15265--->父pid:15262--->fork_return: 0----->p_2
15265 is a child procress!
now pid:15262--->父pid:14413--->fork_return:15266----->p_3
now pid:15262--->父pid:14413--->fork_return:15267----->p_4
now pid:15267--->父pid:15262--->fork_return: 0----->p_4
15267 is a child procress!
now pid:15266--->父pid:15262--->fork_return: 0----->p_3
15266 is a child procress!

这时由 15262产生了15263,15264,15265,15266,15267
可以看出所有子进程都在15262里fork出的,是15262的直接子进程

php里进程创建和分析的更多相关文章

  1. Linux内核分析--进程创建,执行,切换

    学号:351 原创作品转载请注明出处本实验来源 https://github.com/mengning/linuxkernel/ 实验要求 从整理上理解进程创建.可执行文件的加载和进程执行进程切换,重 ...

  2. 从整体上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换

    学号后三位<168> 原创作品转载请注明出处https://github.com/mengning/linuxkernel/ 1.分析fork函数对应的内核处理过程sys_clone,理解 ...

  3. Windows进程创建的流程分析

    .   创建进程的大体流程:   创建进程的过程就是构建一个环境,这个环境包含了很多的机制 (比如自我保护, 与外界通信等等). 构建这个环境需要两种"人"来协调完成(用户态和内核 ...

  4. Android虚拟机器学习总结Dalvik虚拟机创建进程和线程分析

    Dalvik调用一个成员函数时,虚拟机,假设发现,该成员函数是一个JNI办法,然后,它会直接跳转到其地址来运行.也就是说.JNI方法是直接在本地操作系统上运行的.而不是由Dalvik虚拟机解释器运行. ...

  5. Linux-进程描述(4)之进程优先级与进程创建执行

    进程优先级 进程cpu资源分配就是指进程的优先权(priority).优先权高的进程有优先执行权利. 权限与优先级.权限(privilege)是指在多用户计算机系统的管理中,某个特定的用户具有特定的系 ...

  6. python的multiprocessing模块进程创建、资源回收-Process,Pool

    python的multiprocessing有两种创建进程的方式,每种创建方式和进程资源的回收都不太相同,下面分别针对Process,Pool及系统自带的fork三种进程分析. 1.方式一:fork( ...

  7. Linux学习--进程创建

    进程创建 在Linux系统下,自己可以创建进程: 当进程执行时,它会被装载进虚拟内存,为程序变量分配空间,并把相关信息添到 task_struct里. 进程内存布局分为四个不同的段: • 文本段,包含 ...

  8. 进程创建过程详解 CreateProcess

    转载请您注明出处:http://www.cnblogs.com/lsh123/p/7405796.html 0x01 CreateProcessW CreateProcess的使用有ANSI版本的Cr ...

  9. 理解Android进程创建流程(转)

    /frameworks/base/core/java/com/android/internal/os/ - ZygoteInit.java - ZygoteConnection.java - Runt ...

随机推荐

  1. CodePen最佳实例分享

    原文地址: Chris Coyier's Favorite CodePen Demos 原文日期: 2013年8月13日 翻译日期: 2013年8月21日 CodePen: Build, Explor ...

  2. javascript之DOM文档对象模型编程的引入

    /* DOM(Document Object Model) 文档对象模型 一个html页面被浏览器加载的时候,浏览器就会对整个html页面上的所有标签都会创建一个对应的 对象进行描述,我们在浏览器上看 ...

  3. struts2 令牌 实现源代码 JSP

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...

  4. 一个炫字都不够??!!!手把手带你打造3D自定义view

    分享一则最近流行的笑话: 最新科学研究表明:寒冷可以使人保持年轻,楼下的王大爷表示虽然今年已经60多岁了,但是仍然冷的跟孙子一样. 呃.好吧,这个冬天确实有点冷,在广州活生生的把我这个原生北方人,冻成 ...

  5. 数据结构基础(2) --顺序查找 & 二分查找

    顺序查找 适用范围: 没有进行排序的数据序列 缺点: 速度非常慢, 效率为O(N) //实现 template <typename Type> Type *sequenceSearch(T ...

  6. How To Transact Move Order Using INV_PICK_WAVE_PICK_CONFIRM_PUB.Pick_Confirm API

    In this Document Goal   Solution   Sample Code:   Steps:   FAQ   References APPLIES TO: Oracle Inven ...

  7. tomcat生产部署关键参数设置

    JVM设置 个节点,每个tomcat预计处理500个链接,那么连接池的长连接数最大设为2000. 全节点复制(DeltaManager)模式集群节点数3-6为宜. 主备复制(BackupMnagage ...

  8. 集群通信组件tribes之通道拦截器

    拦截器应该可以说是一个很经典的设计模式,它有点类似于过滤器,当某信息从一个地方流向目的地的过程中,可能需要统一对信息进行处理,如果考虑到系统的可扩展性和灵活性通常就会使用拦截器模式,它就像一个个关卡被 ...

  9. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  10. ros_indigo使用keyboard键盘控制虚拟或实际机器人

    首先,上参考网址: http://wiki.ros.org/Robots/TIAGo http://wiki.ros.org/teleop_twist_keyboard 第一个,使用TIAGo的gaz ...