当前位置: 首页 > 面试题库 >

PHP为系统调用的脚本设置超时,set_time_limit不起作用

龙成仁
2023-03-14
问题内容

我有一个命令行PHP脚本,该脚本使用带有foreach的数组的每个成员运行wget请求。这个wget请求有时可能会花费很长时间,因此,例如,如果它超过15秒,我希望能够设置超时以终止脚本。我禁用了PHP安全模式,并在脚本的早期尝试了set_time_limit(15),但是它会无限期地继续。
更新: 感谢Dor指出这是因为set_time_limit()不尊重system()调用。

因此,我试图找到其他方法来在执行15秒后杀死脚本。但是,我不确定是否可以同时在wget请求中间检查脚本运行的时间(do
while循环不起作用)。也许用一个计时器派生一个进程,并将其设置为在一定时间后杀死父进程?

感谢您的提示!

更新: 以下是我的相关代码。$ url是从命令行传递的,它是多个URL的数组(很抱歉,最初没有发布此URL):

foreach( $url as $key => $value){
    $wget = "wget -r -H -nd -l 999 $value";
    system($wget);
    }

问题答案:

您可以结合使用“ –timeout”和time()。首先确定总时间,然后在脚本运行时降低–timeout。

例如:

$endtime = time()+15;
foreach( $url as $key => $value){
  $timeleft = $endtime - time();
  if($timeleft > 0) {
    $wget = "wget -t 1 --timeout $timeleft $otherwgetflags $value";
    print "running $wget<br>";
    system($wget);
  } else {
    print("timed out!");
    exit(0);
  }
}

注意:如果不使用-t,wget将尝试20次,每次等待–timeout秒。

这是使用proc_open / proc_terminate(@Josh的建议)的一些示例代码:

$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("pipe", "w")
);
$pipes = array();

$endtime = time()+15;
foreach( $url as $key => $value){
  $wget = "wget $otherwgetflags $value";
  print "running $wget\n";
  $process = proc_open($wget, $descriptorspec, $pipes);
  if (is_resource($process)) {
    do {
      $timeleft = $endtime - time();
      $read = array($pipes[1]);
      stream_select($read, $write = NULL, $exeptions = NULL, $timeleft, NULL);
      if(!empty($read)) {
        $stdout = fread($pipes[1], 8192);
        print("wget said--$stdout--\n");
      }
    } while(!feof($pipes[1]) && $timeleft > 0);
    if($timeleft <= 0) {
      print("timed out\n");
      proc_terminate($process);
      exit(0);
    }
  } else {
    print("proc_open failed\n");
  }
}


 类似资料:
  • 我有一个类在php中,计算大的数字。它工作得很好,除了时间限制。 我设定了时间限制 在我bigint.php文件里,它在localhost有效。但是在我的网络主机中,当我试图计算999^999时,它会产生错误 致命错误:在第156行的 /home/vhosts/mysite.com/http/bigint/bigint.php中超过了10秒的最大执行时间 这是我的代码: 我试着设置时间限制(900

  • 我有一个php版本为7.0的Linux apache2 Web服务器。22.看起来设置根本不起作用:( 这个ini文件位于以下位置:根据。当我查看文件夹时,我看到三个文件(设置告诉我正在使用的文件),和。 所以我查找了,它是,我将它改为,然后。我对所有的人都这样做了。ini文件保存了它们,重新启动apache2并刷新了phpinfo()页面,但什么都没有发生。我试图在所有窗口中更改其他设置。ini

  • 问题内容: 除了使用繁忙等待或繁忙睡眠循环外,还有什么方法可以使用超时的系统调用? 我有一个本身的父进程和一个子可执行文件。然后,它等待孩子完成操作,以任何适当的方式获取其输出,然后执行进一步的处理。如果该过程在一定时间内未完成,则假定其执行超时,并执行其他操作。不幸的是,鉴于问题的性质,此超时检测是必需的。 问题答案: 没有等待超时的等待呼叫。 您可以做的是安装一个为SIGCHLD设置标志的信号

  • 问题内容: 如果我执行或,则当我在本地主机上回显时,我会得到,但是当我在另一台服务器上执行此操作时,它将回显默认值,并完全忽略我的请求。为什么是这样? 问题答案: 在安全模式下运行时,无法使用ini_set()更改此设置。唯一的解决方法是关闭安全模式或通过更改php.ini中的时间限制。 - PHP手册,运行时配置,描述 许多主机以安全模式运行。其他服务器很可能是其中之一。 编辑:上有相同的限制:

  • #include <stdio.h> int main(void) { char p1[] = "Sam"; char *p2 = "Bob"; printf("p1 is %s, p2 is %s\n", p1, p2); return 0; } 技巧 使用gdb调试程序时,可以使用catch syscall [name | number]为关注的系统调用设

  • 我使用此代码在Java中获取系统代理: 但是“列表”只包含直接设置,而不包含我在Internet Explorer中设置的设置。奇怪的是,在我们软件的早期版本中,完全相同的代码返回正确的系统代理列表。 有人知道是什么可能使代码无法正常工作吗? 我添加了一些本地库,这是我唯一能想到的。但我仍然不知道这会如何影响这段代码。我在一个小测试应用程序中测试了相同的代码,在同一个eclipse环境中,等等。它