((PHP)等待子进程超时退出

问题描述 投票:0回答:1

我使用proc_open()开始了一个子进程,现在我需要等到该子进程完成-或-直到经过X秒,以先到者为准。解决该问题的一种明显方法是while()循环,它会像这样检查每次迭代:

$starttime = microtime(true);
$unused = [];
$ph = proc_open($cmd, $unused, $unused);
$terminated = false; // < protection against running pkilltree() twice
// OPTIMIZE ME: use stream_select() or something instead of sleep-loop
while (($status = proc_get_status($ph))['running']) {
    usleep(100 * 1000); // *1000 = ms
    if (! $terminated && microtime(true) - $starttime > MAX_RUNTIME_SECONDS) {
        $terminated = true;
        echo 'max runtime reached (' . MAX_RUNTIME_SECONDS . ' seconds), terminating...';
        pkilltree((int) ($status['pid']));
        // proc_terminate ( $ph, SIGKILL );
    }
}

但是,如果该过程在1毫秒内完成,那么等待99毫秒的sleep()(相对)浪费了很多时间,我只能每1毫秒而不是每100毫秒检查一次,但这会浪费很多cpu。使用linux api的人可能可以使用sigtimedwait() to wait for SIGCHLD,但是在PHP中,我怀疑(但尚未正确验证)PHP解释器本身会拦截并从userland php代码中隐藏SIGCHLD,所以..有什么建议吗?

php exec wait
1个回答
0
投票

我只是很好奇,是否有必要使用proc_open()?因为可以使用exec()函数作为示例代码,但是需要一个简单的CLI工具才能使用它的timeout

timeout-运行具有时间限制的命令启动COMMAND,然后终止它如果在DURATION之后仍在运行

因此,此代码可替代您的代码,除非您想对孩子做其他事情。

$starttime = microtime(true);
exec("timeout " . MAX_RUNTIME_SECONDS . " $cmd");
$terminated = false;
if (! $terminated && microtime(true) - $starttime > MAX_RUNTIME_SECONDS) {
    $terminated = true;
    echo 'max runtime reached (' . MAX_RUNTIME_SECONDS . ' seconds), terminating...';
}

我在PHP的多处理中使用了多年的技巧。它对我来说非常完美。

© www.soinside.com 2019 - 2024. All rights reserved.