pcntl_fork()函数创建一个子进程,这个子进程仅PID(进程号) 和PPID(父进程号)与其父进程不同
成功时,在父进程执行线程内返回产生的子进程的PID,在子进程执行线程内返回0。失败时,在 父进程上下文返回-1,不会创建子进程

调用函数创建进程的时候,函数执行是有时间的,而新的进程刚好是在函数执行开始和结束之间创建出来的,
这样,新的进程也执行了这个函数,所以函数也需要有返回值。
那么对于该函数一次执行之后,父进程和子进程都会受到该函数的返回值
由于父进程创建了子进程,而子进程并没有创建新的进程,所以子进程对于这个函数的返回结果是没有的,
所以就给他赋了一个0
而父进程创建了子进程,子进程是存在pid的,所以就得到了那个进程的pid

下面不考虑进程创建失败的情况

  1. <?php
  2. echo "###\n";
  3. echo posix_getpid();
  4. echo "\n------------\n";
  5. $i=0;
  6. while($i<2){
  7. $pid = pcntl_fork();
  8. echo "now pid:".sprintf("%5d",posix_getpid())."--->父pid:".sprintf("%5d",posix_getppid())."--->fork_return:".sprintf("%5d",$pid)."----->p_".$i++.PHP_EOL;
  9. }
  10. exit;

输出和简析

  1. ###
  2. 15280
  3. ------------
  4. now pid:15280--->父pid:14413--->fork_return:15281----->p_0
  5. now pid:15281--->父pid:15280--->fork_return: 0----->p_0
  6. now pid:15280--->父pid:14413--->fork_return:15282----->p_1
  7. now pid:15282--->父pid:15280--->fork_return: 0----->p_1
  8. now pid:15281--->父pid:15280--->fork_return:15283----->p_1
  9. now pid:15283--->父pid:15281--->fork_return: 0----->p_1
  10. 发现打印了4p_1
  11. 分析
  12. 当前pid 15280
  13. i=0时记为step1
  14. 15280分裂成15280(pcntl_fork()返回15281)
  15. 15280分裂成15281(pcntl_fork()返回0)
  16. i=1时记为step2
  17. step115280分裂成15280(pcntl_fork()返回15282)
  18. step115280分裂成15282(pcntl_fork()返回0)
  19. step115281分裂成15281(pcntl_fork()返回15283)
  20. step115281分裂成15283(pcntl_fork()返回0)

返回0的表示创建了新的子进程在子进程的返回
现在我们只要2个进程(更多也原理一样)
如果使用循环
比如我们要5个进程

  1. <?php
  2. echo "###\n";
  3. echo posix_getpid();
  4. echo "\n------------\n";
  5. $i=0;
  6. while($i<5){
  7. $pid = pcntl_fork();
  8. echo "now pid:".sprintf("%5d",posix_getpid())."--->父pid:".sprintf("%5d",posix_getppid())."--->fork_return:".sprintf("%5d",$pid)."----->p_".$i++.PHP_EOL;
  9. //子进程里的返回,不再进行while的pcntl_fork
  10. if($pid == 0){
  11. echo posix_getpid()." is a child procress!\n";
  12. return '';
  13. }
  14. }
  15. exit;
  16. ?>

输出

  1. ###
  2. 15262
  3. ------------
  4. now pid:15262--->父pid:14413--->fork_return:15263----->p_0
  5. now pid:15263--->父pid:15262--->fork_return: 0----->p_0
  6. 15263 is a child procress!
  7. now pid:15262--->父pid:14413--->fork_return:15264----->p_1
  8. now pid:15264--->父pid:15262--->fork_return: 0----->p_1
  9. 15264 is a child procress!
  10. now pid:15262--->父pid:14413--->fork_return:15265----->p_2
  11. now pid:15265--->父pid:15262--->fork_return: 0----->p_2
  12. 15265 is a child procress!
  13. now pid:15262--->父pid:14413--->fork_return:15266----->p_3
  14. now pid:15262--->父pid:14413--->fork_return:15267----->p_4
  15. now pid:15267--->父pid:15262--->fork_return: 0----->p_4
  16. 15267 is a child procress!
  17. now pid:15266--->父pid:15262--->fork_return: 0----->p_3
  18. 15266 is a child procress!

这时由 15262产生了15263,15264,15265,15266,15267
可以看出所有子进程都在15262里fork出的,是15262的直接子进程

 

版权声明:本文为HKUI原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/HKUI/p/9017207.html