php - (PHP) 等待子进程超时退出
问题描述
我使用 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() 来等待 SIGCHLD,但在 PHP 中,我怀疑(但尚未正确验证)PHP 解释器本身从用户态 php 代码中拦截并隐藏 SIGCHLD ,所以..有什么建议吗?
解决方案
我只是好奇,是否有必要使用 proc_open()?因为作为您的示例代码,可以使用 exec() 函数来完成它,但它需要一个简单的 CLI 工具来使用,它的timeout
.
timeout - 运行有时间限制的命令 Start 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 中使用多处理。它对我来说非常完美。
推荐阅读
- codenameone - 拉动刷新容器
- python - pkg_resources:未找到“sh”分布,需要 buildozer
- javascript - 防止使用 Javascript 调整图像大小
- angular - 与 Mantra 生物识别设备的离子应用程序连接
- java - 将 JSON 解析为 Java 实体
- c++ - C++ 函数指针
- android - 尝试在 Google Play 控制台中预览我的应用版本并不断出错
- sql - sql这个查询语句的作用是什么
- google-cloud-platform - Google Cloud 存储文件的基本身份验证
- css - 如何使用 React Native 在静态图像上实现网格覆盖