You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ZipArchive::addFile()是否会干扰hrtime()的计时准确性?

问题:ZipArchive::addFile()导致hrtime计时不准?

我写了下面的循环,想让它在10秒后停止:

//open archive $zip
$start = hrtime(true);
while(true) {
  $zip->addFile($files[$i++]);
  $end = hrtime(true);
  $time = ($end - $start) / 1e+9; // convert to seconds
  if( $time > 10.0) {
    break;
  }
}
echo $i;

但计时器没法准确在10秒后停止。换成用sleep模拟工作的循环,就会正常在10秒左右停止:

//open archive $zip
$start = hrtime(true);
while(true) {
  sleep(1); // simulate work

  $end = hrtime(true);
  $time = ($end - $start) / 1e+9; // convert to seconds
  if( $time > 10.0) {
    break;
  }
}
echo $i;

想问下ZipArchive::addFile()会不会影响硬件计时器,导致时间差计算出错?我知道可以用microtime(true),但它在虚拟机环境里准确性可能更低。


解答

首先,ZipArchive::addFile()不会影响硬件计时器,hrtime(true)读取的是系统级的高精度计时器,和单个PHP扩展的操作没有关联。问题出在你的循环逻辑上:

  • 用sleep模拟的循环中,每次sleep(1)后立刻检查时间,逻辑是“完成一次工作后判断是否超时”,而且sleep本身是阻塞操作,时间计算的时机很稳定。
  • 但在addFile的循环里,你是每次调用addFile之后才检查时间。如果addFile执行耗时较长(比如处理大文件、磁盘IO速度慢),那这次操作可能直接让总耗时超过10秒很多,才会触发break。举个例子:如果第9次循环后总耗时是9秒,第10次addFile花了2秒,执行完检查时总耗时已经是11秒,自然停止时间不准。

另外,hrtime(true)本身是可靠的,它不会被PHP的IO操作干扰,问题完全是循环内的时间检查时机不对。如果要更精准控制超时,应该在每次循环开始前先检查时间,而非做完耗时操作后再检查:

//open archive $zip
$start = hrtime(true);
$i = 0;
while(true) {
  // 先检查是否超时,再执行耗时操作
  $end = hrtime(true);
  $time = ($end - $start) / 1e+9;
  if($time > 10.0) {
    break;
  }
  $zip->addFile($files[$i++]);
}
echo $i;

这样就能保证一旦超时就立刻停止,不会因为某次addFile的耗时导致超时过多。microtime(true)确实在虚拟机环境可能存在精度问题,所以继续使用hrtime是更优的选择。


内容的提问来源于stack exchange,提问作者theking2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:15:59