2011-01-19 52 views
6

我正在用popen()打开一个长时间运行的进程。为了调试,我想在完成之前终止该过程。调用pclose()只是阻塞,直到孩子完成。用popen()打开杀死进程?

我该如何杀死这个过程?我没有看到任何简单的方法来从popen()返回的资源中获取pid,以便我可以向它发送一个信号。

我想我可以做一些kludgey并试图捏造PID为使用某种命令行两轮牛车的输出...

+0

这不是一个真正的答案,因为它适用于C而不是PHP,但请参阅此链接以获取建议:http://www.monkey.org/openbsd/archive/misc/0112/msg00360.html – 2011-01-19 04:14:50

回答

7

那么,降落在一个解决方案:我切换回proc_open()而不是popen()。然后,它的那样简单:

$s = proc_get_status($p); 
posix_kill($s['pid'], SIGKILL); 
proc_close($p); 
+0

我和`proc_open()`有同样的问题,所以我尝试了更简单的`popen()`,希望这会有所帮助。当时我没有意识到* * pclose()和`proc_close()`阻塞,直到孩子终止。一旦你意识到这一点,那么你必须杀死孩子。要杀死孩子,你需要使用pid,这并不是用`popen()`完全可用的。 `proc_open()`做一切`popen()`做的,然后一些。 – 2011-01-19 04:20:44

0

使用kill功能只需发送kill(或中止)信号:

+0

棘手的部分在搞清楚哪个pid要杀死的时候做得很好:)一旦你确定你有正确的pid,那么你可以调用php的`posix_kill()`。我想现在回想起来,我可以从ps中获得孩子pid的列表,因为很容易找出我自己的pid。 – 2011-01-19 04:16:36

0

您可以找到PID,那你真的其父做检查:

// Find child processes according to current pid 
$res = trim(exec('ps -eo pid,ppid |grep "'.getmypid().'" |head -n2 |tail -n1')); 
if (preg_match('~^(\d+)\s+(\d+)$~', $res, $pid) !== 0 && (int) $pid[2] === getmypid()) 
{ 
    // I'm the parent PID, just send a KILL 
    posix_kill((int) $pid[1], 9); 
} 

它的工作非常好快的CGI PHP的服务器上。