PHP会公开其内部超时时钟吗?

r1zhe5dt  于 2023-10-15  发布在  PHP
关注(0)|答案(2)|浏览(95)

默认情况下,php在30秒的CPU时间后终止脚本,即sleep s,并且等待网络响应的时间大多不计算在内。
此外,在每次调用set_time_limit时,此内部时间保持被重置。
PHP必须在内部跟踪一个进程使用了多少CPU时间,是否有可靠的方法来获取此信息?
如果可能的话,我希望有一个函数可以告诉我还有多少时间。

eh57zj3b

eh57zj3b1#

试试这个,你可以得到CPU的执行时间。

// Record the start time
$startUsage = getrusage();

// Your PHP code here

// Record the end time
$endUsage = getrusage();

// Calculate CPU time
$cpuTime = ($endUsage['ru_utime.tv_sec'] - $startUsage['ru_utime.tv_sec']) +
       ($endUsage['ru_utime.tv_usec'] - $startUsage['ru_utime.tv_usec']) / 1000000;

echo "CPU time used: {$cpuTime} seconds";
wqsoz72f

wqsoz72f2#

为了它的价值,我试图创建一些可移植的函数来做到这一点。这是我写的代码。在我的机器上,我的Apache服务器被设置为30秒后超时,当我将for循环设置为60亿时,它会超时,但它会在50亿时运行几秒钟。sleep()不计入使用,但我有prefork mpm模块。当我有时间再看一遍的时候,我会看看它在其他mpm模块上做了什么。
如果getrusage()函数不可用,那么它只会使用运行时间,我认为运行时间应该安全地大于或等于CPU时间。我想让它也使用经过时间,如果它不是在mpm prefork上,但我不认为有一种方法来确定这在PHP中没有执行httpd,这似乎是矫枉过正。如果我错了,请告诉我。无论如何,请随意评论或提出如何改进它的建议。
它返回秒,我认为如果函数的make目的只是确保脚本以有序的方式完成而不是超时,那么这就足够了。我觉得你可以写一句

if(!Is_Bool($remainingtime) && $remainingtime < 5) saveandquit();

给给予足够的时间来完成它需要做的事情,以安全地完成。这是代码。

<?php

function is_cli() {
  if (function_exists('http_response_code')) {
    return (http_response_code() === false);
  }
  return !isset($_SERVER['REMOTE_ADDR']);
}

function getstarttime() {
  if (function_exists('getrusage')) {
    $rusage = getrusage();
    if (isset($rusage['ru_utime.tv_sec'])) {
      return $rusage['ru_utime.tv_sec'];
    }
  }
  return time();
}

function gettimeremaining($starttime) {
  // NOTE: May not work as intended if not on mpm prefork
  // Function returns estimate of the number of seconds remaining before script timeout.
  $met = ini_get('max_execution_time');
  if ($met == '0') return false;
  if (function_exists('getrusage')) {
    $rusage = getrusage();
    if (isset($rusage['ru_utime.tv_sec'])) {
      return $met - ($rusage['ru_utime.tv_sec'] - $starttime);
    }
  }
  return $met - (time() - $starttime);
}

$starttime = getstarttime();
$br = "";
if (is_cli()) {
  echo("This is cli.\n");
} else {
  $br = "<br />";
  echo("This is not cli.$br\n");
}
for($i=0;$i<5000000000;$i++); 
sleep(10);
$remainingtime = gettimeremaining($starttime);
if (Is_Bool($remainingtime)) {
  echo("There is no time limit.$br\n");
} else {
  echo "There are $remainingtime seconds remaining before timeout.$br\n";
}
?>

相关问题