xcguoyu 2020-01-05
php是一门单进程弱类型的语言,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,多进程的作用优点大家可以去网上了解,PHP实现多进程在实际项目中意义也是不容小觑的。比如:日常任务中,有时需要通过php脚本执行一些日志分析,队列处理等任务,当数据量比较大时,可以使用多进程来处理。
要实现PHP的多进程,需要用到函数pcntl_fork,那么就需要开启扩展 pcntl和 posix,在上一篇文章已经有安装方法。
入门须知
鸟哥语录(多进程优点)http://www.laruence.com/2009/06/11/930.html
切记!切记!切记!
创建子进程(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
$ppid = posix_getpid(); $pid = pcntl_fork(); if ($pid == -1) { echo ‘fork子进程失败!‘; } elseif ($pid > 0) { echo "我是父进程,我的进程id是{$ppid}."; echo "\r\n"; sleep(20); // 保持20秒,确保能被ps查到 }else{ $cpid = posix_getpid(); echo "我是{$ppid}的子进程,我的进程id是{$cpid}."; echo "\r\n"; sleep(20); // 保持20秒,确保能被ps查到 }
php fork.php //centos下执行命令 我是父进程,我的进程id是7625. 我是7625的子进程,我的进程id是7626.
# ps aux | grep fork.php //centos下20秒内执行命令 root 7625 0.0 0.6 143892 6496 pts/1 S+ 03:27 0:00 php fork.php root 7626 0.0 0.4 143892 4252 pts/1 S+ 03:27 0:00 php fork.php root 7628 7.0 0.0 103268 860 pts/2 S+ 03:27 0:00 grep fork.php
posix_getpid()函数作用是:获取当前进程的pid;
进一步说明
上边的代码如果创建子进程成功的话,系统就有了2个进程,一个为父进程,一个为子进程,子进程的id号为$pid。在系统运行到$pid = pcntl_fork();时,在这个地方进行分支,父子进程各自开始运行各自的程序代码。代码的运行结果是父进程那块代码 和子进程的代码都走了,很奇怪吧,为什么一个elseif和else互斥的代码中,都输出了结果?其实是像上边所说的,代码在pcntl_fork时,一个父进程运行父进程那块代码,一个子进程运行了子进程那块代码。在代码结果上就显示了“我是父进程....”和"我是子进程..."。至于谁先谁后的问题,这得要看系统资源的分配了
<?php. if (!empty($_POST)) {. $data1 = $_POST["data1"];$data2 = $_POST["data2"];$fuhao = $_POST["fuh