PHP time() 和 microtime() 有时不一致


php time() and microtime() do sometimes not concord

在使用microtime()(使用PHP 5)记录一些数据时,我遇到了一些与日志文件时间戳似乎有点不相的值,所以我只是尝试将time()和microtime()的输出与一个简单的脚本进行比较(usleep只是为了限制数据输出):

<?php
for($i = 0; $i < 500; $i++) {
    $microtime = microtime();
    $time = time();
    list($usec, $sec) = explode(" ", $microtime);
    if ((int)$sec > $time) {
        echo $time . ' : ' . $microtime . '<br>';
    }
    usleep(50000);
}
?>

现在,由于$microtime在$time之前声明,我希望它更小,并且不应该输出任何内容;但是,情况显然并非如此,并且时不时地,$time小于从microtime()返回的秒数,如以下示例(截断)输出:

1344536674 : 0.15545100 1344536675
1344536675 : 0.15553900 1344536676
1344536676 : 0.15961000 1344536677
1344536677 : 0.16758900 1344536678

现在,这只是一个小差距;然而,我观察到一些系列的差异(相当)超过一秒钟......那么,这怎么可能呢?

如果你看一下 timemicrotime 的实现,你会发现它们完全不同:

  • time只是调用 C time函数。
  • microtime有两种实现:如果 C 函数gettimeofday可用(它应该在 Linux 系统上),则称为直截了当。否则,他们会拉一些杂技来使用诡计来计算时间。

由于 C time 调用只能精确到一秒,因此它也可能有意使用低保真时间源。

此外,在现代x86_64系统上,通过查看某些 CPU 寄存器,可以在没有系统调用的情况下实现这两个 C 函数。如果您使用的是多核系统,则这些寄存器在内核之间可能不完全匹配,这可能是一个原因。

差异的另一个潜在原因是NTPd(计时守护进程)或其他一些用户空间进程正在更改时钟。通常,这些影响应通过adjtime来避免。

所有这些理由都非常深奥。若要进一步调试问题,应:

  • 确定操作系统和 CPU 架构(提示:告诉我们!
  • 尝试将该过程强制到一个内核上
  • 停止任何正在(或可能)调整系统时间的程序。

这可能是由于 microtime() 使用浮点数,因此可能会出现舍入错误。

您可以在 php 中指定浮点数的精度.ini