PHP进程执行超时
我有以下代码:
/**
* Executes a program and waits for it to finish, taking pipes into account.
* @param string $cmd Command line to execute, including any arguments.
* @param string $input Data for standard input.
* @param integer $timeout How much to wait from program in msecs (-1 to wait indefinitely).
* @return array Array of "stdout", "stderr" and "return".
*/
function execute($cmd,$stdin=null,$timeout=-1){
$proc=proc_open(
$cmd,
array(array('pipe','r'),array('pipe','w'),array('pipe','w')),
$pipes=null
);
fwrite($pipes[0],$stdin); fclose($pipes[0]);
$stdout=stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr=stream_get_contents($pipes[2]); fclose($pipes[2]);
$return=proc_close($proc);
return array(
'stdout' => $stdout,
'stderr' => $stderr,
'return' => $return
);
}
它有两个“问题”。
- 代码是同步的;它会冻结,直到目标进程关闭。
- 到目前为止,如果不发出不同类型的命令(例如 Linux 上的
$cmd > /dev/null &
和start / B $cmd 在 Windows 上)
我根本不介意“冻结”。我只需要实现该超时。
注意:该解决方案的跨平台兼容非常重要。同样重要的是, $cmd
不必更改 - 我正在运行一些复杂的命令,恐怕可能会出现一些问题,但是,这取决于修复的类型 -我很高兴听到这些,只是我更喜欢不同的选择。
我找到了一些可能有帮助的资源:
I have the following code:
/**
* Executes a program and waits for it to finish, taking pipes into account.
* @param string $cmd Command line to execute, including any arguments.
* @param string $input Data for standard input.
* @param integer $timeout How much to wait from program in msecs (-1 to wait indefinitely).
* @return array Array of "stdout", "stderr" and "return".
*/
function execute($cmd,$stdin=null,$timeout=-1){
$proc=proc_open(
$cmd,
array(array('pipe','r'),array('pipe','w'),array('pipe','w')),
$pipes=null
);
fwrite($pipes[0],$stdin); fclose($pipes[0]);
$stdout=stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr=stream_get_contents($pipes[2]); fclose($pipes[2]);
$return=proc_close($proc);
return array(
'stdout' => $stdout,
'stderr' => $stderr,
'return' => $return
);
}
It has two "problems".
- The code is synchronous; it freezes until the target process closes.
- So far, I've not been able to it from "freezing" without issuing a different kind of command (such as
$cmd > /dev/null &
on linux andstart /B $cmd
on windows)
I don't mind the "freeze", at all. I just need to implement that timeout.
Note: It is important that the solution is cross-platform compatible. It is also important that the $cmd
doesn't have to change - I'm running some complex commands and I'm afraid there may be some issues, however, this depends on the type of fix - I'm happy to hear these out, just that I'd prefer a different alternative.
I've found some resources that may help:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
代码中有一些错误。
这实际上是有效的:
There is a few mistakes on the code.
That is actually working:
您可以考虑使用
fread
来更精细地控制代码正在执行的操作,而不是stream_get_contents
。与 stream_set_timeout 相结合可能会为您提供所需的内容。我把一些东西放在一起,作为我认为可能有效的演示 - 该代码完全未经测试,并且不提供任何保证,但可能会将您引向正确的方向。 ;)
Rather than
stream_get_contents
, you could look at usingfread
to gain more finely grained control over what your code is doing. That combined with stream_set_timeout may give you what you're looking for.I tossed something together as a demonstration of what I was thinking might work - this code is completely untested and comes with no guarantees, but might send you in the right direction. ;)
这似乎对我有用:
我不确定
stream_set_timeout
的目的是什么 - 只是设置每次读取超时,但如果你想限制总体时间,你只需将流设置为非阻塞模式,然后计算所需的时间。This seems to be working for me:
I'm not sure what the purpose of
stream_set_timeout
is -- that just sets the per-read timeout, but if you want to limit the overall time, you just have to set the stream to non-blocking mode and then time how long it takes.