我看了你之前回到的代码,有个地方我感觉有点疑问。
function stopAll($sig){
echo "master has a sig $sig\n" ;
}
$master_id = getmypid();
$pid = pcntl_fork();
if($pid > 0)
{
pcntl_signal(SIGINT,'stopAll') ;
$epid = pcntl_wait($status,WUNTRACED);
pcntl_signal_dispatch();
echo "parent process {$master_id}, child process {$pid}\n";
if($epid){
echo "child $epid exit \n" ;
}
}
else
{
$id = getmypid();
echo "child process,pid {$id}\n";
sleep(6);
echo "send signal to master\n";
posix_kill($master_id, SIGINT);
while(true){
sleep(3);
}
}
这是你之前写的代码,我只是在else里面加了一个循环,保证子进程不会中断。这样,就算之前发送了posix_kill($master_id, SIGINT)信号,信号回调函数还是不会触发
你好,你的父进程执行到pcntl_wait就挂起了,一直在等待子进程结束,而子进程因为while循环一直没有结束,所以父进程后面的代码并不会执行。
我想父进程里的代码可以调整成这样:
pcntl_signal(SIGINT, 'stopAll');
sleep(7);
// 因为子进程sleep了6秒才发信号过来,所以这里等待大于6秒的时间才把信号分发给回调函数
pcntl_signal_dispatch();
// 发送终止子进程的信号
posix_kill($pid, SIGTERM);
// pcntl_wait等到子进程终止后继续执行后续代码
$epid = pcntl_wait($status);
这几天又再学习了下,按你原来的代码,给pcntl_signal加个参数就行:
pcntl_signal(SIGINT, 'stopAll', false);
个人理解:在有信号来时,pcntl_wait会中断一下再恢复。上面第三个参数默认是true,恢复的点是在wait之前,所以恢复后继续wait阻塞;设置成false时,恢复会在wait之后,执行后面的代码。