2、案例
2.1、源码
<?php
/
Copyright (C) Iamasb
@project : 3、workerman干系知识点
@filename : 27、父子进程旗子暗记通信.php
@author : iamasb 2801616735@qq.com
/
// 固定进程数
$count = 2;
// 存放进程数组
$pidArr = array();
$masterPid = posix_getpid();
// 注册旗子暗记
pcntl_signal(SIGQUIT,\"大众sigFunc\"大众,false);
function sigFunc($sig){
global $pidArr,$masterPid;
$pid = posix_getpid();
$ppid = posix_getppid();
switch($sig){
case SIGQUIT:
if( count($pidArr) && ($pid == $masterPid) ){
echo \公众master-->\"大众,PHP_EOL;
foreach ( $pidArr as $k=>$v ){
posix_kill($v,SIGQUIT);
unset($pidArr[$k]);
}
}else{
echo \公众pid = {$pid} ppid={$ppid} \公众,PHP_EOL;
exit;
}
break;
}
}
for($i=0;$i<$count;$i++){
$pid = pcntl_fork();
if( $pid > 0 ){
// 父进程
$pidArr[$i] = $pid;
}elseif ($pid == 0){
// 子进程
echo \"大众子进程pid-->\"大众.posix_getpid().PHP_EOL;
while( 1 ){
pcntl_signal_dispatch();
sleep(2);
}
exit;
}else{
exit(\"大众fork fail.\"大众);
}
}
echo \公众父进程id->\"大众,$masterPid,PHP_EOL;
print_r($pidArr);
// 父进程监控
while(1){
pcntl_signal_dispatch();
// 壅塞获取正常退出的子进程id
$pid = pcntl_wait($status,WUNTRACED);
pcntl_signal_dispatch();
if( $pid > 0 ){
echo \公众{$pid} is over\公众,PHP_EOL;
}
if (empty($pidArr)) {
echo 'master is over';
exit;
}
}
2.2、实行结果
新开shell终端,实行kill命令,kill -s SIGQUIT 17304
kill父进程 kill -s SIGQUIT 173033、把稳事变知识点: 旗子暗记是可以中断 wait 等系统调用的
在源码中,pcntl_signal函数的第三个参数设置为false,这个参数是代表进程在收到旗子暗记后是内核是否重启系统调用,默认是true。也便是说,当收到主进程收到旗子暗记后,pcntl_wait立即被中断并返回了-1。这里的-1是代表非常出错。而这个非常是由于主进程收到旗子暗记后,中断了wait操作。