参考:https://blog.csdn.net/jason314/article/details/5640969

1.fork简介


一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
fork调用的一个奇妙之处是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值: 在父进程中,fork返回新创建子进程的进程ID;
在子进程中,fork返回0;
如果出现错误,fork返回一个负值; 关于fork出来的进程PID不同的解释: 进程形成了链表,父进程的pid(p 意味point)指向子进程的进程id。 子进程没有子进程,所以其fpid为0。
可以通过fork返回的值来判断当前进程是子进程还是父进程。 父子进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略
<?php

/**
* fork_demo.php
* @desc:单进程
*/
$count= 0;
$fpid = pcntl_fork();
if ($fpid < 0) {
echo "error in fork!";
} else if ($fpid == 0) {
//子进程执行空间
//getmypid()可在Windows和Linux上执行,获取当前进程PID
echo sprintf("i am the child process, my process id is %d\n",getmypid());
$count++;
} else {
//父进程执行空间
//posix_getpid()只能在Linux上执行,获取当前进程PID
echo sprintf("i am the parent process, my process id is %d\n",posix_getpid());
$count++;
}
echo sprintf("the count of result: %d\n", $count); ?>

执行结果:

2.fork进阶

<?php
/**
* fork_demo2.php
* @desc:多进程
*/
define('FORK_NUMS', 2); echo "i son/pa ppid pid fpid\n";
//ppid 指当前进程的父进程
//pid指当前进程
//fpid指fork返回给当前进程的值
for($i=0; $i<FORK_NUMS; $i++){
$fpid = pcntl_fork();
if($fpid<0){
echo "fork error";
}else if($fpid == 0){
$format = "%d child %5d %5d %5d\n";
echo sprintf($format, $i, posix_getppid(), posix_getpid(), $fpid);
}else{
$format = "%d parent %5d %5d %5d\n";
echo sprintf($format, $i, posix_getppid(), posix_getpid(), $fpid);
}
}

执行结果:

代码解析:
1.第一步:在父进程中,指令执行到for循环中,$i=0,接着执行fork,系统中出现两个进程,分别是p33584和p33585(后面我都用pxxxx表示进程id为xxxx的进程)。可以看到父进程p33584的父进程是p31166,子进程p33585的父进程正好是p33584。我们用一个链表来表示这个关系:
  p31166->p33584->p33585
  第一次fork后,p33584(父进程)的变量为$i=0,$fpid=33585(fork函数在父进程中返向子进程pid) 2.第二步:假设父进程p33584先执行,当进入下一个循环时,$i=1,接着执行fork,系统中又新增一个进程p33586,对于此时的父进程,p31166->p33584(当前进程)->p33585(被创建的子进程)。
  对于子进程p33585,执行完第一次循环后,$i=1,接着执行fork,系统中新增一个进程p33587,对于此进程,p33584->p33585(当前进程)->p33587(被创建的子进程)。从输出可以看到p33585原来是p33584的子进程,现在变成p33587的父进程。父子是相对的,这个大家应该容易理解。只要当前进程执行了fork,该进程就变成了父进程了,就打印出了parent。 3.第三步:第二步创建了两个进程p33586,p33587,这两个进程执行完sprintf函数后就结束了,因为这两个进程无法进入第三次循环,无法fork,其他进程也是如此。 4.程序最终产生了3个子进程,执行过6次sprintf()函数。 5.流程图如下:

Linux下fork机制详解(以PHP为例)的更多相关文章

  1. 【转】linux 中fork()函数详解

    在看多线程的时候看到了这个函数,于是学习了下,下面文章写的通俗易懂,于是就开心的看完了,最后还是很愉快的算出了他最后一个问题. linux 中fork()函数详解 一.fork入门知识 一个进程,包括 ...

  2. linux下tar命令详解

     linux下tar命令详解    tar是Linux环境下最常用的备份工具之一.tar(tap archive)原意为操作磁带文件,但基于Linux的文件操作机制,同样也可适用于普通的磁盘文件.ta ...

  3. Linux环境fork()函数详解

    Linux环境fork()函数详解 引言 先来看一段代码吧, 1 #include <sys/types.h> 2 #include <unistd.h> 3 #include ...

  4. Linux下ps命令详解 Linux下ps命令的详细使用方法

    http://www.jb51.net/LINUXjishu/56578.html Linux下的ps命令比较常用 Linux下ps命令详解Linux上进程有5种状态:1. 运行(正在运行或在运行队列 ...

  5. Linux下rar命令详解

    Linux下rar命令详解 用法: rar <命令> -<选项1> ….-<选项N> < 操作文档> <文件…> <@文件列表…> ...

  6. Linux下chkconfig命令详解(转)

    Linux下chkconfig命令详解 chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. ...

  7. Linux知识积累(4) Linux下chkconfig命令详解

    Linux下chkconfig命令详解 chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. ...

  8. Linux下top命令详解

    Linux下top命令详解 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.top是一个动态显示过程,即可以通过用户按键来不断刷 ...

  9. 转载的 Linux下chkconfig命令详解

    Linux下chkconfig命令详解 chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. ...

随机推荐

  1. Unity3D 优化NGUI纹理

    原理就是将一张rgba 32的分成两张纹理:一张平台压缩不带alpha和一张为原图1/4大小的压缩图存储alpha信息(用r分量当alpha值),然后修改原材质的Shader传入这两张纹理. 代码如下 ...

  2. jenkins之 pipeline 小尝试

    最近,一个小需求,动态建立slave节点来执行自动化用例,原有jenkins 老方式不满足需求,就用到jenkins2的pipeline来实现,但在实现过程中,2个小坑记录下 1.jenkins不能读 ...

  3. Python不支持函数重载

    函数重载与Python: 函数重载的好处就是不用为了不同的参数类型或参数个数,而写多个函数.多个函数用同一个名字,但参数表,即参数的个数和数据类型可以不同.调用的时候,虽然方法名字相同,但根据参数表可 ...

  4. day2 二、编程语言、python解释器和变量

    一.编程语言分类 1.机器语言 直接用计算机能理解的二进制指令编写程序,直接控制硬件,需要了解硬件的操作细节. 2.汇编语言 用英文标签取代二进制编写程序,也是直接控制硬件,也需要了解硬件的操作细节. ...

  5. 泡泡一分钟:A Multi-Position Joint Particle Filtering Method for Vehicle Localization in Urban Area

    A Multi-Position Joint Particle Filtering Method for Vehicle Localization in Urban Area 城市车辆定位的多位置联合 ...

  6. Arrays 类的一些常见用法

    package cn.ljs; import java.util.Arrays; public class ArrayDemo { public static void main(String [] ...

  7. [No0000111]java9环境变量配置bat

    保存成bat(utf-8 无签名 编码) 右键以管理员权限运行 修改JAVAINSTALLPATH 为JAVA SDK 安装目录(默认用C:\PROGRAM FILES\JAVA\)即可: 只在 用户 ...

  8. Oracle分析函数大全

    分析函数又叫开窗函数,OLAP函数等,因为有人问我用过开窗函数没,呵,什么是开窗函数,从来没听过,难道是分析函数么.哈哈,最后还真是分析函数哦!用过的东西别名也应该知道,赶上这么个事,就剽窃一眼Ora ...

  9. shell监控之列出1小时内cpu占用最多的10个进程

    脚本内容如下: -------------------------------------------------------------------------------------------- ...

  10. Redis的概念及与MySQL的区别

    学了MySQL相关知识后,了解到很多公司都会用mysql+redis互补使用的,今天学习整理一下Redis的相关知识. 首先是Redis和MySQL的区别: MySQL是典型的关系型数据库:Redis ...