代码如下:
$count = 1 ;
echo $count;
echo "\r\n";
echo "main pid=".posix_getpid()."\r\n";
for ($i = 0; $i<2;$i++)
{
echo "for start:pid=".posix_getpid()." i=".$i."\r\n";
$pid = pcntl_fork();
echo "fork pid=".$pid."\r\n";
if($pid>0){
$count++;
}elseif ($pid==0){
echo "child pid=".posix_getpid()." i=".$i."\r\n";
$count*=10;
}
echo "for end:pid=".posix_getpid()." i=".$i."\r\n";
}
echo "pid=".posix_getpid()." count=".$count."finish\r\n";
echo "\r\n";
return 0;
A、父进程的代码从第 1 行运行到 16 行结束,每次运行时 count++【count++ 为右值运算】,运行到 16 行后结果为 3。
B、父进程在运行到 6 行时,发起一个系统调用,等待系统 fork 一个新的进程【我起个名字叫 child1 子进程】,第一次运行时 count=1,i=0,fork 之后子进程的代码和父进程完全一样,没有什么变化(实在不理解,可以想想复制粘贴或是想想 github 的 forking 工作流,你 fork 人家的项目的时候,得到的数据就是人家目前最新的数据,如果说你过几天再 fork 数据就变了【假设仓库的所有者更新了源码】)
此时 count=1,i=0,fork 之后产生了第一个子进程。我起名为 child_1,此时该子进程的代码和父进程完全一样。
然后:
我们继续看父进程,pid 在父进程中它的值大于 0,执行 coun++【右值运算】,然后运行到第 14 行,第一次 for 循环结束,此时 i=1,count=2;
同理执行 fork 系统调用,产生第二个子进程,我起名为 child_2,此时该子进程的数据为 i=1,count=2;
然后:
继续看父进程,执行到 14 行时循环结束,i=2,count=3;
此时父进程 for 循环完全结束,回到了第 15 行打印结果 $count=3;
该子进程占用的是独立的存储空间,复制父进程的数据时 i=0,count=1,它会从第 7 行开始运行,自然在本进程中,pid=0,为什么?因为该进程目前是先从第 7 行开始运行的,它不是从第 7 行前面运行的,pid 自然就为 0 了,表示是自己,然后运行第 10 行的 else 分支,求得 count=10,然后运行到 14 行,此时第一次 for 循环结束,i=1,
然后:
child_1 进程运行第 6 行执行 fork 系统调用,此时我起名为 child_3 进程,它复制的数据此时为 i=1,count=10;
child_1 进程继续运行,自然满足 pid>0 的条件,此时 i=2,整个循环结束,最终运行 15 行得到 count=11;
此时复制的数据是 i=1,count=2;,同样的从 7 行开始运行可是只满足 else 分支执行 count=2*10; 然后运行 14 行,整个循环结束了 i=2,
此时复制的数据为 i=1,count=10; 它的爸爸是 child_1 进程,同样的从第 7 行开始运行嘛,自然满足 else 分支 count=100 了,此时循环结束 i=2;
父进程分别 fork 了 child_1 进程,child_2 进程,child_1 进程 fork 了 child_3 进程 进程间关系树如下
父进程
—-child_1
——–child_3
—-child_2
$count = 1 ;
echo $count;
echo "\r\n";
echo "main pid=".posix_getpid()."\r\n";
for ($i = 0; $i<2;$i++)
{
echo "for start:pid=".posix_getpid()." i=".$i."\r\n";
$pid = pcntl_fork();
echo "fork pid=".$pid."\r\n";
if($pid>0){
$count++;
}elseif ($pid==0){
echo "child pid=".posix_getpid()." i=".$i."\r\n";
$count*=10;
break;
}
echo "for end:pid=".posix_getpid()." i=".$i."\r\n";
}
echo "pid=".posix_getpid()." count=".$count."finish\r\n";
echo "\r\n";
return 0;
i=0;count=1; 此时产生一个子进程,我也起名为 child_1【当然了系统会用进程描述符来标识】 此时执行第 7 行满足 count=2; 然后运行到 14 行,第一次循环结束,此时 i=1;
i=1;count=2; 此时也执行 fork 系统调用,产生了一个 child_2 子进程,同样的也只满足第 7 行的代码,执行 count=3,然后运行 14 行,整个循环结束 i=2;
复制得来的数据为 i=0;count=1,此时也从 7 行开始运行,但是也只满足 else 分支算得
复制得来的数据为 i=1,count=2,同样的从第 7 行开始运行,也只满足 else 分支运行求得
进程之间的关系
主进程
—- child_1
—- child_2
linux【先调用 exec 系列函数调用】开始运行,进程遇到 return,exit 或最后一条语句或是外部的中断信号即终止。