pcntl_wait 信号触发问题

qpao123

我看了你之前回到的代码,有个地方我感觉有点疑问。

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)信号,信号回调函数还是不会触发

阅读 2254
2个回答

t182848232

你好,你的父进程执行到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);

  • 暂无评论
t182848232

这几天又再学习了下,按你原来的代码,给pcntl_signal加个参数就行:

pcntl_signal(SIGINT, 'stopAll', false);

个人理解:在有信号来时,pcntl_wait会中断一下再恢复。上面第三个参数默认是true,恢复的点是在wait之前,所以恢复后继续wait阻塞;设置成false时,恢复会在wait之后,执行后面的代码。

  • 暂无评论