在使用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
现在,这只是一个小差距;然而,我观察到一些系列的差异(相当)超过一秒钟......那么,这怎么可能呢?
如果你看一下 time
和 microtime
的实现,你会发现它们完全不同:
-
time
只是调用 Ctime
函数。 -
microtime
有两种实现:如果 C 函数gettimeofday
可用(它应该在 Linux 系统上),则称为直截了当。否则,他们会拉一些杂技来使用诡计来计算时间。
由于 C time
调用只能精确到一秒,因此它也可能有意使用低保真时间源。
此外,在现代x86_64系统上,通过查看某些 CPU 寄存器,可以在没有系统调用的情况下实现这两个 C 函数。如果您使用的是多核系统,则这些寄存器在内核之间可能不完全匹配,这可能是一个原因。
差异的另一个潜在原因是NTPd(计时守护进程)或其他一些用户空间进程正在更改时钟。通常,这些影响应通过adjtime
来避免。
所有这些理由都非常深奥。若要进一步调试问题,应:
- 确定操作系统和 CPU 架构(提示:告诉我们!
- 尝试将该过程强制到一个内核上
- 停止任何正在(或可能)调整系统时间的程序。
这可能是由于 microtime() 使用浮点数,因此可能会出现舍入错误。
您可以在 php 中指定浮点数的精度.ini