set_time_limit不影响PHP-CLI [英] set_time_limit is not affecting PHP-CLI
问题描述
如何解决不影响PHP-CLI的set_time_limit?
How to solve set_time_limit not affecting PHP-CLI?
#!/usr/bin/php -q
<?php
set_time_limit(2);
sleep(5); // actually, exec() call that takes > 2 seconds
echo "it didn't work again";
推荐答案
此处的解决方案是使用pcntl_fork()
.恐怕仅是POSIX. PHP将需要使用--enable-pcntl
而不是--disable-posix
进行编译.您的代码应如下所示:
The solution here is to use pcntl_fork()
. I'm afraid it's POSIX only. PHP will need to be compiled with --enable-pcntl
and not --disable-posix
. Your code should look something like this:
<?php
function done($signo)
{
// You can do any on-success clean-up here.
die('Success!');
}
$pid = pcntl_fork();
if (-1 == $pid) {
die('Failed! Unable to fork.');
} elseif ($pid > 0) {
pcntl_signal(SIGALRM, 'done');
sleep($timeout);
posix_kill($pid, SIGKILL);
// You can do any on-failure clean-up here.
die('Failed! Process timed out and was killed.');
} else {
// You can perform whatever time-limited operation you want here.
exec($cmd);
posix_kill(posix_getppid(), SIGALRM);
}
?>
基本上,这是创建一个运行else { ... }
块的新进程.最后(成功),我们将警报发送回运行elseif ($pid > 0) { ... }
块的父进程.该块具有用于警报信号(done()
回调)的已注册信号处理程序,该信号处理程序成功终止.在接收到该消息之前,父进程将进入休眠状态.超时sleep()
完成后,它将向SIGKILL
.
Basically what this does is fork a new process which runs the else { ... }
block. At the (successful) conclusion of that we send an alarm back to the parent process, which is running the elseif ($pid > 0) { ... }
block. That block has a registered signal handler for the alarm signal (the done()
callback) which terminates successfully. Until that is received, the parent process sleeps. When the timeout sleep()
is complete, it sends a SIGKILL
to the (presumably hung) child process.
这篇关于set_time_limit不影响PHP-CLI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!