超时在PHP函数超时在PHP函数(Timeout a function in PHP)

2019-05-14 02:50发布

有没有一种方法超时功能? 我有10分钟进行的工作。 作业包括一个循环,下面是一个例子:

<?php
foreach($arr as $key => $value){
   some_function($key, $value); //This function does SSH and SFTP stuff
}
?>

$ ARR有15个元件和some_function()有时可能需要超过1分钟。 事实上,一旦它得到绞死5分钟。

有没有一种方法可以让我超时函数调用,并在$ ARR下一个元素感动吗?

谢谢!!

Answer 1:

这取决于您的实现。 在PHP功能99%的阻塞。 这意味着处理将不会继续,直到目前的功能已经完成。 但是,如果函数包含了循环,你可以在自己的代码添加到中断循环一定的条件已经满足之后。

事情是这样的:

foreach ($array as $value) {
  perform_task($value);
}

function perform_task($value) {
  $start_time = time();

  while(true) {
    if ((time() - $start_time) > 300) {
      return false; // timeout, function took longer than 300 seconds
    }
    // Other processing
  }
}

其中中断处理另一个示例是不可能的:

foreach ($array as $value) {
  perform_task($value);
}

function perform_task($value) {
    // preg_replace is a blocking function
    // There's no way to break out of it after a certain amount of time.
    return preg_replace('/pattern/', 'replace', $value);
}


Answer 2:

PHP是单线程的......你必须使用你的操作系统的叉另一个进程的能力。

我知道如何做到这一点的唯一方法是使用exec命令到餐桌了另一个全过程。 把你想在一个单独的脚本定时的东西,呼吁脚本EXEC,然后马上入睡10分钟。 如果在10分钟的进程仍在运行杀死它。 (你应该有它的PID通过使命令运行新的PHP代码的背景下,通过命令行得到它,并从exec命令返回的话)。



Answer 3:

你想要的是使用pcntl_alarm功能,这将触发超时SIGALRM信号。 例如:

// 10 minutes
pcntl_alarm( 600 );
pcntl_signal( 'SIGALRM', function() { print( "I am done!\n" ); exit( 0 ); } );

请在这里看到的PHP手册更多内容: http://php.net/manual/en/function.pcntl-alarm.php



Answer 4:

你可以尝试实施这一使用“卷曲”。 卷曲 - 从PHP - 主要是用来做什么的HTTP / FTP的东西,但它支持更多的协议,包括SSH / SFTP。 我从来没有做过使用curl相关的东西SSH / SFTP,所以我不能给任何其他建议,但你应该能够在这里找到计算器或其他地方的其他信息。

有一个选项“CURLOPT_TIMEOUT”你可以用它来配置超时您的要求(有也是一个选项“CURLOPT_CONNECTTIMEOUT”)。 你甚至可以指定毫秒分辨率(CURLOPT_TIMEOUT_MS / CURLOPT_CONNECTTIMEOUT_MS)超时。

总之:对于一个cronjob我会建议使用额外的“锁定文件”时,它的启动和删除,当它完成运行的脚本编写。 您可以检查脚本中的这个锁文件,所以如果触发的cron脚本上次运行结束之前 ,你可以退出你的脚本没有任何进一步的做。 这确保,你的脚本就不会并行执行多次。

你可以找到更多的卷曲选项和卷曲本身的PHP文件中,也:

  • http://www.php.net/manual/en/function.curl-setopt.php
  • http://www.php.net/manual/en/book.curl.php

你必须确保,你安装了PHP的libcurl和/或卷曲支持SSH / SFTP,虽然:

  • SFTP从PHP -未定义的常量CURLOPT_PROTOCOLS和CURLPROTO_SFTP?
  • 从PHP内SFTP

等等

希望可以帮助...



Answer 5:

开始进入循环之前,设置记得可变time() 在每次迭代结束时,检查当前time()是超过60秒以上。 如果是这样, break 。 例如:

<?php
$startTime=time();
foreach($arr as $key => $value){
    some_function($key, $value); //This function does SSH and SFTP stuff
    if (time()-$startTime>60) break; //change 60 to the max time, in seconds.
}
?>


Answer 6:

看看参数或者set_time_limit 。 现在,函数本身是不是真的想你想,因为它只考虑了执行时间,这意味着在现实生活中5秒可能仍然是唯一0.2秒执行。 但看着链接的原因是进行了点评。 有用户所发布的一对夫妇的解决方案。



Answer 7:

对于那些你谁是在命令行中,看到的睡眠是如何打断:

echo date("H:i:s\n");
pcntl_signal(SIGALRM ,function($signal){
echo "arghhh! i got interrupted \n";
},true);

pcntl_alarm(3);
sleep(20);
pcntl_signal_dispatch();


echo date("H:i:s\n");

pcntl_alarm(3);
sleep(20);

echo date("H:i:s\n");

pcntl_signal_dispatch();
echo "end\n";


文章来源: Timeout a function in PHP