过去一段时间我尝试使用 proc_open 杀死外部命令遇到了很多问题。
其他人建议使用 ps 查找 proc_get_status 返回的 pid 的子进程,但在我的系统上这不起作用。我使用的是 php-5.2.5 和 apache-2.0.59 在 Linux 内核 2.6.21 上,我使用 proc_open 启动的进程最终由 init(pid 1)拥有,而不是由 proc_get_status 返回的 pid 拥有。
但是,我确实注意到进程的 pid 始终高于 proc_get_status pid 并且非常接近。使用这些信息,我编写了一个小函数,它接受命令名称、要搜索的起始 pid(应该是 proc_get_status pid),以及可选的搜索限制作为参数。它将使用 ps 列出由 apache 拥有的进程(您可能需要为您的系统更改此用户名),并搜索指定的命令。限制指示要在起始 pid 之上搜索多远。这将有助于在命令可能已经退出时,您不想杀死与您正在使用的会话不同的会话中的进程。
代码如下:
<?php
function findCommandPID($command, $startpid, $limit = 3)
{
$ps = `ps -u apache --sort=pid -o comm= -o pid=`;
$ps_lines = explode("\n", $ps);
$pattern = "/(\S{1,})(\s{1,})(\d{1,})/";
foreach($ps_lines as $line)
{
if(preg_match($pattern, $line, $matches))
{
if($matches[3] > $startpid + $limit)
break;
if($matches[1] == $command && $matches[3] > $startpid)
return $matches[3];
}
}
return false;
}
?>