代码之家  ›  专栏  ›  技术社区  ›  tflutre

Resource.getrusage()始终返回0

  •  2
  • tflutre  · 技术社区  · 11 年前

    在脚本结束时,我想返回峰值内存使用情况。阅读后 other questions ,这是我的脚本:

    #!/usr/bin/env python
    import sys, os, resource, platform
    print platform.platform(), platform.python_version()
    os.system("grep 'VmRSS' /proc/%s/status" % os.getpid())
    print resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    dat = [x for x in xrange(10000000)]
    os.system("grep 'VmRSS' /proc/%s/status" % os.getpid())
    print resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    

    下面是我得到的:

    $ test.py
    Linux-2.6.18-194.26.1.el5-x86_64-with-redhat-5.5-Final 2.7.2
    VmRSS:      4472 kB
    0
    VmRSS:    322684 kB
    0
    

    为什么 resource.getrusage 总是返回我0?

    同样的事情在终端中以交互方式发生。这可能是因为Python是专门安装在我的机器上的吗?(这是我与其他人一起使用的计算机集群,由管理员管理。)

    编辑:当我使用子流程时也会发生同样的事情;执行此脚本

    #!/usr/bin/env python
    import sys, os, resource, platform
    from subprocess import Popen, PIPE
    print platform.platform(), platform.python_version()
    p = Popen(["grep", "VmRSS", "/proc/%s/status" % os.getpid()], shell=False, stdout=PIPE)
    print p.communicate()
    print "resource:", resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    dat = [x for x in xrange(10000000)]
    p = Popen(["grep", "VmRSS", "/proc/%s/status" % os.getpid()], shell=False, stdout=PIPE)
    print p.communicate()
    print "resource:", resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    

    给出以下内容:

    $ test.py
    Linux-2.6.18-194.26.1.el5-x86_64-with-redhat-5.5-Final 2.7.2
    ('VmRSS:\t    4940 kB\n', None)
    resource: 0
    ('VmRSS:\t  323152 kB\n', None)
    resource: 0
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   deinonychusaur    11 年前

    以下是替换os.system调用的方法

    In [131]: from subprocess import Popen, PIPE
    
    In [132]: p = Popen(["grep", "VmRSS", "/proc/%s/status" % os.getpid()], shell=False, stdout=PIPE)
    
    In [133]: p.communicate()
    Out[133]: ('VmRSS:\t  340832 kB\n', None)
    

    我也没有问题运行您觉得有问题的线路:

    In [134]: print resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    340840
    

    编辑

    rusage问题很可能是一个依赖于内核的问题,在您的红帽dist上根本不可用 http://bytes.com/topic/python/answers/22489-getrusage

    当然,您可以在代码中有一个单独的线程来查看当前的使用情况,并在代码执行过程中进行存储,并存储观察到的最高值

    编辑2

    这里有一个完整的解决方案,通过Popen跳过资源和监视使用情况。检查的频率当然必须是相关的,但不是频繁的,这样会占用所有的cpu。

    #!/usr/bin/env python
    
    import threading
    import time
    import re
    import os
    from subprocess import Popen, PIPE
    
    maxUsage = 0
    keepThreadRunning = True
    
    
    def memWatch(freq=20):
    
        global maxUsage
        global keepThreadRunning
    
        while keepThreadRunning:
    
            p = Popen(["grep", "VmRSS", "/proc/%s/status" % os.getpid()],
                      shell=False, stdout=PIPE)
    
            curUsage = int(re.search(r'\d+', p.communicate()[0]).group())
    
            if curUsage > maxUsage:
    
                maxUsage = curUsage
    
            time.sleep(1.0 / freq)
    
    
    if __name__ == "__main__":
    
        t = threading.Thread(target=memWatch)
        t.start()
    
        print maxUsage
        [p for p in range(1000000)]
        print maxUsage
        [str(p) for p in range(1000000)]
        print maxUsage
        keepThreadRunning = False
        t.join()
    

    memWatch函数可以通过计算一次睡眠时间来优化,而不是在进入while循环之前重新格式化每个循环的进程路径和编译正则表达式。但总而言之,我希望这就是你所追求的功能。