2、案例

2.1、源码

<?php

/

php父子54php应用旌旗灯号实现父子过程间通讯 JavaScript

Copyright (C) Iamasb

@project : 3、workerman干系知识点

@explain : 父子进程旗子暗记通信

@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 17303

3、把稳事变

知识点: 旗子暗记是可以中断 wait 等系统调用的

在源码中,pcntl_signal函数的第三个参数设置为false,这个参数是代表进程在收到旗子暗记后是内核是否重启系统调用,默认是true。
也便是说,当收到主进程收到旗子暗记后,pcntl_wait立即被中断并返回了-1。
这里的-1是代表非常出错。
而这个非常是由于主进程收到旗子暗记后,中断了wait操作。