到底有几个进程在运行

PHP原始多进程实现以及运行流程

代码如下:

$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 数据就变了【假设仓库的所有者更新了源码】)

父进程第一次 fork 时:

此时 $count=1,$i=0,fork 之后产生了第一个子进程。我起名为 child_1,此时该子进程的代码和父进程完全一样。

然后:

我们继续看父进程,$pid 在父进程中它的值大于 0,执行 $coun++【右值运算】,然后运行到第 14 行,第一次 for 循环结束,此时 $i=1,$count=2;

父进程第二次 fork 时:

同理执行 fork 系统调用,产生第二个子进程,我起名为 child_2,此时该子进程的数据为 $i=1,$count=2;

然后:

继续看父进程,执行到 14 行时循环结束,$i=2,$count=3;

此时父进程 for 循环完全结束,回到了第 15 行打印结果 $count=3;

child_1 子进程的运行工作过程

该子进程占用的是独立的存储空间,复制父进程的数据时 $i=0,$count=1,它会从第 7 行开始运行,自然在本进程中,$pid=0,为什么?因为该进程目前是先从第 7 行开始运行的,它不是从第 7 行前面运行的,$pid 自然就为 0 了,表示是自己,然后运行第 10 行的 else 分支,求得 $count=10,然后运行到 14 行,此时第一次 for 循环结束,$i=1,$count=10;

然后:

child_1 进程运行第 6 行执行 fork 系统调用,此时我起名为 child_3 进程,它复制的数据此时为 $i=1,$count=10;

child_1 进程继续运行,自然满足 $pid>0 的条件,此时 $count=10+1; 然后跑到第 14 行,$i=2,整个循环结束,最终运行 15 行得到 $count=11;

child_2 子进程的运行工作过程

此时复制的数据是 $i=1,$count=2;,同样的从 7 行开始运行可是只满足 else 分支执行 $count=2*10; 然后运行 14 行,整个循环结束了 $i=2,$count=20;

child_3 进程的运行工作过程

此时复制的数据为 $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

加上 break 之后呢??

$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;

父进程第一次 fork

$i=0;$count=1; 此时产生一个子进程,我也起名为 child_1【当然了系统会用进程描述符来标识】 此时执行第 7 行满足 $count=2; 然后运行到 14 行,第一次循环结束,此时 $i=1;

父进程第二次 fork

$i=1;$count=2; 此时也执行 fork 系统调用,产生了一个 child_2 子进程,同样的也只满足第 7 行的代码,执行 $count=3,然后运行 14 行,整个循环结束 $i=2;

child_1 子进程的运行

复制得来的数据为 $i=0;$count=1,此时也从 7 行开始运行,但是也只满足 else 分支算得 $count=10; 然后遇到 break 整个循环结束。

child_2 子进程的运行

复制得来的数据为 $i=1,$count=2,同样的从第 7 行开始运行,也只满足 else 分支运行求得 $count=20; 遇到 break 结束整个循环。

进程之间的关系

主进程

—- child_1

—- child_2

进程的启动和结束

linux【先调用 exec 系列函数调用】开始运行,进程遇到 return,exit 或最后一条语句或是外部的中断信号即终止。

本文原文博客骚颠颠 骚颠颠

北溟有鱼QAQ博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论