我们都知道PHP是单进程执行的,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,但PHP实现多进程也意义重大,尤其是在后台Cli模式下处理大量数据或运行后台DEMON守护进程时,多进程的优势不用多说。

PHP的多线程也曾被人提及,但进程内多线程资源共享和分配的问题难以解决。PHP也有多线程想关的扩展 pthreads ,但据说不太稳定,且要求环境为线程安全,所用不多。

以前PHP群里的一位大神曾指导说后台PHP想进阶必然避不开多进程,正好公司里的守护进程也应用了PHP的多进程,结合着谷哥的各种资料和手册,总算理解了多进程。

要实现PHP的多进程,我们需要两个扩展 pcntl 和 posix,安装方法这里不再赘述。

在php中我们使用pcntl_fork()来创建多进程(在*NIX系统的C语言编程中,已有进程通过调用fork函数来产生新的进程)。fork出来新进程则成为子进程,原进程则成为父进程,子进程拥有父进程的副本。这里要注意:

• 子进程与父进程共享程序正文段

• 子进程拥有父进程的数据空间和堆、栈的副本,注意是副本,不是共享

• 父进程和子进程将继续执行fork之后的程序代码

• fork之后,是父进程先执行还是子进程先执行无法确认,取决于系统调度(取决于信仰)

这里说子进程拥有父进程数据空间以及堆、栈的副本,实际上,在大多数的实现中也并不是真正的完全副本。更多是采用了COW(Copy On Write)即写时复制的技术来节约存储空间。简单来说,如果父进程和子进程都不修改这些 数据、堆、栈 的话,那么父进程和子进程则是暂时共享同一份 数据、堆、栈。只有当父进程或者子进程试图对 数据、堆、栈 进行修改的时候,才会产生复制操作,这就叫做写时复制。

在调用完pcntl_fork()后,该函数会返回两个值。在父进程中返回子进程的进程ID,在子进程内部本身返回数字0。由于多进程在apache或者fpm环境下无法正常运行,所以大家一定要在php cli环境下执行代码。

创建子进程

创建PHP子进程是多进程的开始,我们需要pcntl_fork()函数;

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,当然也不会有子进程产生。

fork进程实例

fork子进程

$ppid = posix_getpid();$pid = pcntl_fork();if ($pid == -1) { throw new Exception('fork child process fail');} elseif ($pid > 0) { cli_set_process_title("我是父 process,pid is : {$ppid}."); sleep(30);} else { $cpid = posix_getpid(); cli_set_process_title("我是 {$ppid} 子的 process,我的 process pid is : {$cpid}."); sleep(30);}

说明:

posix_getpid():返回当前进程 id

cli_set_process_title('进程名称'):为当前进程取一个响亮的名字。

运行这个例子,我们便能看到当前两个PHP进程了。

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ ps aux|grep -v grep |grep 我www 18026 0.5 1.2 204068 25772 pts/0 S+ 14:08 0:00 我是父 process,pid is : 18026.www 18027 0.0 0.3 204068 6640 pts/0 S+ 14:08 0:00 我 18026 子的 process,我的 process pid is : 18027. 

第一段代码,在程序从pcntl_fork()后父进程和子进程将各自继续往下执行代码:

$pid = pcntl_fork();if( $pid > 0 ){ echo "我是父亲".PHP_EOL;} else if( 0 == $pid ) { echo "我是儿子".PHP_EOL;} else { echo "fork失败".PHP_EOL;} 

结果:

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php 123.php我是父亲我是儿子

第二段代码,用来说明子进程拥有父进程的数据副本,而并不是共享:

// 初始化一个 number变量 数值为1$number = 1;$pid = pcntl_fork();if ($pid > 0) { $number += 1; echo "我是父亲,number+1 : { $number }" . PHP_EOL;} else if (0 == $pid) { $number += 2; echo "我是儿子,number+2 : { $number }" . PHP_EOL;} else { echo "fork失败" . PHP_EOL;}

结果

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php 1234.php我是父亲,number+1 : { 2 }我是儿子,number+2 : { 3 }

delphi pid判断进程结束_PHP7是如何实现多进程的?相关推荐

  1. delphi pid判断进程结束_有两个这样的进程:僵尸进程amp;孤儿进程,蓝瘦香菇

    进程 先来说下什么是进程: 来看下百度是怎么说的: 光看说的不够形象,在windows系统中,它长这样: 在Mac系统中,它长这样: Linux中是这样的:(有点长截图一部分好了) [root@iz2 ...

  2. 根据pid判断某个进程是否存在

    http://www.2cto.com/os/201212/177333.html 根据pid判断某个进程是否存在 #命令"ps -af"的第一列就是进程id www.2cto.c ...

  3. win python 判断 所有 子进程 结束_python 多进程 进程池子进程结束怎么获取

    匿名用户 1级 2016-10-26 回答 在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间.当被操作对象数目不大时,可以直接利用mu ...

  4. DOS中判断进程是否存在的方法

    这里分享的主要是通过批处理中先判断进程是否存在,然后再做出操作的实现代码,需要的朋友可以参考下 检测进程是否存在,并做出预定动作. tasklist /nh>d:\tddown~1\1.txt ...

  5. 【Linux系统编程】进程的控制:结束进程、等待进程结束

    结束进程 首先,我们回顾一下 C 语言中 continue, break, return 的作用: continue: 结束本次循环 break: 跳出整个循环,或跳出 switch() 语句 ret ...

  6. Linux 等待进程结束 wait() 和 waitpid()

    若子进程先于父进程结束时,父进程调用wait()函数和不调用wait()函数会产生两种不同的结果: --> 如果父进程没有调用wait()和waitpid()函数,子进程就会进入僵死状态. -- ...

  7. python判断线程结束_判断Threading.start新线程是否执行完毕的实例

    新写自己的Threading类 class MyThread(threading.Thread):#我的Thread类 判断流程结束没 用于os shell命令是否执行判断 def __init__( ...

  8. DOS或命令行下查看进程,结束进程命令

    DOS或命令行下查看进程,结束进程命令  XP中和进程有关的命令: 在system32目录中,dir task* 会看到如下几个文件: +------------------------------+ ...

  9. 511遇见易语言模块API教程进程结束和进程取自进程ID

    当我们多线程多窗口启动游戏时,在退出时我们手动比较麻烦,可以使用进程结束一键退出. 511遇见易语言模块API教程 1.GetCurrentProcessId 获取当前进程一个唯一的标识符 说明: 获 ...

最新文章

  1. 【Java】“异常”详解
  2. IOS7的一个神奇的Bug
  3. docker镜像常见命令
  4. VLC视频播放器原理详细分析含TS流格式分析
  5. Document Builder: 如何将structure level的field加入到word document的table中
  6. HTML的footer置于页面最底部
  7. 使用html css js实现计算器
  8. oftc注册服务器占用,golang服务器程序运行过程中崩溃,报错:fatal error: runtime: out of memory...
  9. 输入过滤筛选下拉信息(类似百度输入)
  10. php计算对角线,python计算对角线有理函数插值的方法
  11. [推荐]HLSL编程实现PhotoShop滤镜效果
  12. 编译器-有限自动机和正则表达式
  13. ubuntu2004使用Renesas upd720202 扩展卡
  14. C语言 定时器的原理,单片机定时器作用原理及学习应用详解
  15. Dubbo Monitor 分析
  16. 手机python代码查询四六级准考证_四六级查准考证号的网站是什么
  17. ios闹钟铃声实现代码
  18. C语言实现文件分割功能
  19. 西西里的美丽传说:美的绽放、挣扎与凋零
  20. java批量添加注解到所有业务接口

热门文章

  1. showdoc windows 搭建_showdoc的安装和使用
  2. python库下载安装报错_Python 各种库的安装
  3. Python跨目录引用模块(文件)
  4. linux知识点查阅
  5. tableau度量值计算_Tableau可视化(雷达图):漫威英雄能力值
  6. python获取eth0_详解 Python 获取网卡 IP 地址的黑魔法
  7. linux下图像分析程序,三 - Linux+C语言:数字图像处理源程序_Linux编程_Linux公社-Linux系统门户网站...
  8. python列表求和显示unsupport_本地使用pip命令安装requests库,提示unknow or unsupported command install解决方法...
  9. java内存溢出排查top_process-parse-shell
  10. 行上下移动_这有一台你迟早要用到的手持式“移动空调”