PHP进程简述

php中的进程是以扩展的形式来完成。通过这些扩展,我们能够很轻松的完成进程的一系列动作。

pcntl扩展:主要的进程扩展,完成进程创建于等待操作。。

  •     构建此扩展不需要其他扩展。
  •     在PHP中进程控制支持默认是关闭的。您需要使用 --enable-pcntl 配置选项重新编译PHP的 CGI或CLI版本以打开进程控制支持。
  •     此扩展没有在 php.ini 中定义配置指令。
  •     此扩展没有定义资源类型。

  • 当前,这个模块没有非Unix平台可用的函数(即非Unix类系统不支持此模块)。

     

posix扩展:完成posix兼容机通用api,如获取进程id,杀死进程等。

  •     构建此扩展不需要其他扩展。
  •     POSIX functions are enabled by default. You can disable POSIX-like functions with --disable-posix .
  •     此扩展没有在 php.ini 中定义配置指令。
  •     此扩展没有定义资源类型。


关于fork后的执行顺序:

 0) {
        echo 'parent'
    }
    pcntl_waitpid($pid , $status, 0); //等待子进程结束
    echo 'BB_end';
}
aa();
/*
AA_start
BB_start
parent
son
AA_end
BB_end        //父进程被阻塞了 要等子进程执行完才会继续 所以父进程最后输出
AA_end
*/
// BB_end只输出了一次;AA_END输出了两次,也是说fork子进程,子进程的后续代码是完全遵循父进程的代码顺序的;此时就需要将return更改为exit 直接关闭就可以了

 象下面代码可以直接return:

 1,
    'son_b' => 2,
    'son_c' => 3,
    'son_d' => 4,
];
$pids = [];
foreach ($sons as $k => $v) {
    $pids[$k] = pcntl_fork();   //1.为当前进程创建一个子进程,并且先运行父进程,返回的是子进程的PID;子/父进程都从此处开始执行
    if ($pids[$k] == 0 ) {      //3.再执行此处代码
        $pid = posix_getpid();
        echo $k.'_'.$pid.PHP_EOL;
        sonOut($v);
        return;                 //4.在子进程的代码块中最好有exit/return语句,即执行完子进程后立即就结束。否则它也会执行 第一步中的创建进程
    } elseif ($pids[$k] > 0) {  //2.先执行此处代码
        echo $k."_parent:".posix_getpid().PHP_EOL;
    }
}

function sonOut($v) {
    for ($i=1; $i <= $v; $i++){
        echo $v.'_'.'_'.$i.PHP_EOL;
        if($v == 4){
            echo PHP_EOL;
        }
        sleep(1);
    }
    
}
$status = '';
foreach ($pids as $pid) {
    $res = pcntl_waitpid($pid, $status,0);//在父进程的代码中用 pcntl_waitpid($pid,&$status)阻塞父进程直到他的子进程有返回值
    echo $res.'_'.$status.PHP_EOL;
}
exit('end');

 


[root@iZbp1hs2rode8m3mzs1jjpZ public]# php pcntl.php
son_a_parent:7972
son_a_7973
1__1
son_b_parent:7972
son_b_7974
2__1
son_c_parent:7972
son_d_parent:7972
son_c_7975
3__1
son_d_7976
4__1

2__2
3__2
4__2

7973_0
3__3
4__3

7974_0
4__4

7975_0
7976_0

进程信号:

pcntl_signal — 安装一个信号处理器
       pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls = true ] ) : bool
pcntl_signal_dispatch — 调用每个等待信号通过pcntl_signal() 安装的处理器。
       pcntl_signal_dispatch ( void ) : bool  

pcntl_signal的实现原理是,触发信号后先将信号加入一个队列中。
然后在PHP的ticks回调函数中不断检查是否有信号,
如果有信号就执行PHP中指定的回调函数,如果没有则跳出函数。
 
ticks=1表示每执行1行PHP代码就回调此函数。
实际上大部分时间都没有信号产生,但ticks的函数一直会执行。 

比较好的做法是去掉ticks,转而使用pcntl_signal_dispatch,在代码循环中自行处理信号。

比较两段代码

第一段

 

[root@iZbp1hs2rode8m3mzs1jjpZ public]# php api.php
1585023396.5262_安装信号处理器...
为自己生成SIGHUP信号...
1585023396.5263_信号处理器被调用
分发...
完成

第二段

1585023348.3601_安装信号处理器...
为自己生成SIGHUP信号...
分发...
1585023351.3603_信号处理器被调用
完成

仔细看信号调用的时间戳 使用declare(ticks = 1); 创建信号时候 立即就调用了;如果去掉declare(ticks = 1); 改用pcntl_signal_dispatch则在pcntl_signal_dispatch调用后执行调用函数

你可能感兴趣的:(PHP,pcntl,php进程)