5

(PHP 5 を使用して) microtime() を使用していくつかのデータをログに記録しているときに、ログ ファイルのタイムスタンプに関してわずかに位相がずれているように見えるいくつかの値に遭遇したので、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

さて、これはほんの小さなギャップです。ただし、違いが(かなり)1秒以上あるシリーズをいくつか観察しました...では、これはどのように可能ですか?

4

2 に答える 2

6

と の実装を見るtimemicrotime、根本的に異なっていることがわかります。

  • timeCtime関数を呼び出すだけです。
  • microtimeには2 つの実装があります。C 関数gettimeofdayが使用可能な場合 (Linux システム上にあるはずです)、それは簡単に呼び出されます。そうでなければ、彼らはいくつかのアクロバットを引っ張って、時間を計算するために rusage を使用します。

Ctime呼び出しは 1 秒までしか正確ではないため、忠実度の低いタイム ソースを意図的に使用することもあります。

さらに、最新の x86_64 システムでは、特定の CPU レジスタを調べることで、両方の C 関数をシステム コールなしで実装できます。マルチコア システムを使用している場合、これらのレジスタがコア間で正確に一致しない可能性があり、それが原因である可能性があります。

不一致のもう 1 つの潜在的な理由は、NTPd (時間管理デーモン) またはその他のユーザー空間プロセスがクロックを変更していることです。通常、これらの種類の影響は によって回避する必要がありますadjtime

これらの理論的根拠はすべてかなり難解です。問題をさらにデバッグするには、次のことを行う必要があります。

  • OS と CPU アーキテクチャを決定します(ヒント: 教えてください!)
  • プロセスを 1 つのコアに強制してみる
  • システム時刻を調整している (または調整している可能性がある) プログラムをすべて停止します。
于 2012-08-09T18:59:27.977 に答える
0

これは、microtime() が浮動小数点数を使用しているため、丸め誤差が発生する可能性があるためです。

php.ini で浮動小数点数の精度を指定できます

于 2013-03-06T10:27:09.383 に答える