代码之家  ›  专栏  ›  技术社区  ›  Andrew Ensley

PHP getrusage()返回错误信息?

  •  4
  • Andrew Ensley  · 技术社区  · 14 年前

    我正在尝试确定PHP脚本的CPU使用率。我刚发现 this article 它详细说明了如何找到系统和用户的CPU使用时间(第4节)。

    然而,当我尝试这些例子时,我得到了完全不同的结果。

    这个 :

    sleep(3);
    
    $data = getrusage();
    echo "User time: ".
        ($data['ru_utime.tv_sec'] +
        $data['ru_utime.tv_usec'] / 1000000);
    echo "System time: ".
        ($data['ru_stime.tv_sec'] +
        $data['ru_stime.tv_usec'] / 1000000);
    

    结果:

    User time: 29.53
    System time: 2.71
    

    例2

    for($i=0;$i<10000000;$i++) {
    
    }
    
    // Same echo statements
    

    结果:

    User time: 16.69
    System time: 2.1
    

    例3

    $start = microtime(true);  
    while(microtime(true) - $start < 3) {  
    
    }  
    
    // Same echo statements
    

    结果:

    User time: 34.94
    System time: 3.14
    

    除了第三个例子中的系统时间。那我做错什么了?我真的很想使用这些信息,但它必须是可靠的。

    我使用的是ubuntuserver8.04lts(32位),这是 php -v

    PHP 5.2.4-2ubuntu5.10 with Suhosin-Patch 0.9.6.2 (cli) (built: Jan  6 2010 22:01:14)
    Copyright (c) 1997-2007 The PHP Group
    Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    
    2 回复  |  直到 12 年前
        1
  •  2
  •   Marc B    14 年前

    您可以使用系统“time”命令从外部验证此信息:

    /usr/bin/time php script.php
    

    它将打印如下内容:

    0.03user 0.00system 0:03.04elapsed 0%CPU (0avgtext+0avgdata 32752maxresident)k
    0inputs+0outputs (0major+2234minor)pagefaults 0swaps
    

    当然,不要忘记getrusage()信息是CPU使用时间,microtime()是挂钟时间。根据墙上的时钟,程序可以运行10分钟,但在内部可能只使用几秒钟的CPU时间。然后是与系统上运行的所有后台程序争夺CPU时间、资源争用以及常规的内务管理。

    要在如此短的时间内得到准确的时间安排,涉及的因素太多了。跑了三圈 while(microtime()) 你的循环版本,我得到了以下计时:

    用户:0.98、0.09、0.90 系统:0.12、0.05、0.94

    很明显,差异很大。即使只是一个简单的 <? print_r(getrusage()) ?> utime/stimes介于0到0.03之间。

        2
  •  0
  •   Community CDub    7 年前

    多亏了 Marc B's advice ,我发现时间短得离谱导致了 getrusage()

    我已经创建了一个解决方法来丢弃这些不准确的数字。代码如下:

    define('SCRIPT_START', microtime(1));
    
    register_shutdown_function('record_activity');
    
    /* Do work here */
    
    function record_activity()
    {
        $data = getrusage();
        $cpuu = ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000);
        $cpus = ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000);
        $renderedtime = round(microtime(1) - SCRIPT_START, 6);
    
        // Have some log function to put this info somewhere
        insert_record($renderedtime,
            //Only pass user CPU time if it's less than or equal to rendered time
            ($renderedtime >= $cpuu ? $cpuu : NULL ),
            //Only pass system CPU time if it's less than or equal to rendered time
            ($renderedtime >= $cpus ? $cpus : NULL ));
    }
    

    希望这对其他遇到同样问题的人有所帮助。