美文网首页
php进程认识

php进程认识

作者: ysp123 | 来源:发表于2019-05-09 20:57 被阅读0次

1、基本认识
php系统提供了pcntl_fork 函数来操作进程。
pcntl_fork:当前进程位置产生分支(子进程)。fork是创建了一个子进程,父进程和子进程 都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程号,而子进程得到的是0。

$pid = pcntl_fork();   //创建子进程
if($pid < 0){
      echo "子进程创建失败".PHP_EOL;
}elseif($pid){
      echo "子进程pid --   ".$pid.PHP_EOL;
}else{
       echo "执行子进程 ---".posix_getpid().PHP_EOL;
}

2、孤儿进程
孤儿进程:一个父进程退出,而它的子进程或多个子进程还在运行,那么那些子进程将成为孤儿进程,孤儿进程将被init进程(进程号为1)收养,并由init进程对他们完成状态收集。
孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。

$pid = pcntl_fork();   //创建子进程
if($pid < 0){
      echo "子进程创建失败".PHP_EOL;
}elseif($pid){
      echo "子进程pid --   ".$pid.PHP_EOL;
}else{
       sleep(30); 
       echo "执行子进程 ---".posix_getpid().PHP_EOL;
}

3、僵尸进程
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,父进程没有调用wait或 waitpid获取子进程的状态信息,那么子进程的描述符任然保存在系统中。这种进程称为僵尸进程。
任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。 如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。
对于linux系统来说,一个长时间运行的多进程程序一定要回收子进程,因为系统的进程资源是有限的,僵尸进程会让系统的可用资源减少。

$pid = pcntl_fork();   //创建子进程
if($pid < 0){
      echo "子进程创建失败".PHP_EOL;
}elseif($pid){
      sleep(30);   //主进程被挂起,30秒内为退出
      echo "子进程pid --   ".$pid.PHP_EOL;
}else{
       echo "执行子进程 ---".posix_getpid().PHP_EOL;
}

上边我们已经说了僵尸进程的危害,那么如何避免僵尸进程。使用

pcntl_wait($status);  //该函数阻塞当前进程,只到当前进程的一个子进程退出或者收到一个结束当前进程的信号
 pcntl_waitpid($pid, $status);  //pcntl_waitpid()和pcntl_wait()功能相同。前者第一个参数支持指定pid参数,当指定-1作为pid的值等同于后者。
$pid = pcntl_fork();   //创建子进程
if($pid < 0){
      echo "子进程创建失败".PHP_EOL;
}elseif($pid){
      pcntl_wait($status);  或  pcntl_waitpid($pid, $status);
      sleep(30);   //主进程被挂起,30秒内为退出
      echo "子进程pid --   ".$pid.PHP_EOL;
}else{
       echo "执行子进程 ---".posix_getpid().PHP_EOL;
}

以上是单进程进程回收,下边我们看下多进程的进程回收,阻塞的回收方式和以上一样,下边我们使用非阻塞

pcntl_wait($status, WNOHANG);
 pcntl_waitpid($pid, $status, WNOHANG);  
$child_pids = [];

for($i=0;$i<3;$i++){
    $pid = pcntl_fork();
    if($pid<0){
        exit('进程创建失败!!');
    }elseif($pid){
          //$res = pcntl_wait($status, WNOHANG);
          //$res =  pcntl_waitpid($pid, $status, WNOHANG);
          echo "父进程pid --". posix_getppid()."  子进程pid  ".$pid;
    }else{
        echo "执行子进程".posix_getpid();
        exit();   //子进程需要exit,防止子进程也进入for循环。如果没有exit(),最终创建的子进程不只3个。
    }
}

while(count($child_pids)){
      foreach($child_pids as $key => $pid){
            //$res = pcntl_wait($status, WNOHANG);
            $res =  pcntl_waitpid($pid, $status, WNOHANG);
            //var_dump($res);
            //exit();
            if ($res == -1 || $res > 0){
                    echo time()." Child process exit,pid {$pid}\n";   
                   unset($child_pids[$key]);
             }else{
                  echo time()." Wait End,pid {$pid}\n";   
             }
      }
}

以上及实现了进程的非阻塞(备足:若结果不明显则加大进程数)

学习编程就是升级打怪的过程。从最开始的静态页面到动态页面,从基本的curd到业务架构,数据存储到大数据处理,从基本的http请求到网络处理,每一次技能的上升都是一次打怪升级。

相关文章

  • php进程认识

    1、基本认识php系统提供了pcntl_fork 函数来操作进程。pcntl_fork:当前进程位置产生分支(子进...

  • PHP中的“进程”系列1——PHP-FPM模型

    PHP中的“进程”系列 这个系列会分几个部分,从PHP-FPM进程模式起,到Linux进程,最后回到PHP本身谈一...

  • 杀掉所有grep到的进程

    以php进程为例 grep php 查询关键字带有php的进程(查询结果会带有grep php)grep -v g...

  • PHP创建守护进程

    PHP 创建守护进程 执行守护进程

  • 2019-06-27

    用PHP玩转进程之二 — 多进程PHPServer 2018-09-02 系统设计 语言 PHP 经过用 PHP ...

  • [PHP] - 编译参数 --enable-pcntl

    官网:PHP - PCNTL 红框翻译 PHP进程控制支持 实现了类unix的进程创建、程序运行、消息处理、进程终...

  • php-fpm

    php-fpm说明 php-fpm是FastCGI的实现,并提供进程管理的功能。进程包括master进程和work...

  • php-fpm解读-进程管理的三种模式

    《我是程序媛》系列——php-fpm进程管理,感谢大表哥亲情赞助时间,读了php-fpm源码。 php-fpm进程...

  • PHP 技能精进之 PHP-FPM 多进程模型

    PHP-FPM 提供了更好的 PHP 进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置。那么当我们谈论...

  • PHP-FPM

    PHP-FPM(PHP FastCGI Process Manager简称,意思是PHP FastCGI的进程管理...

网友评论

      本文标题:php进程认识

      本文链接:https://www.haomeiwen.com/subject/inmgoqtx.html