2017-02-26 143 views
2

我正在寻找一个快速,轻量级的方式从一个Python脚本读取系统正常运行时间。有没有办法从Python调用sysinfo Linux系统调用?最快的方式获得系统正常运行时间在Python在Linux中

到目前为止,我已经找到了另外两种方法测量的正常运行时间,一个涉及运行的外部进程,另一个涉及/proc读取文件。

import subprocess 

def uptime1(): 
    raw = subprocess.check_output('uptime').decode("utf8").replace(',', '') 
    days = int(raw.split()[2]) 
    if 'min' in raw: 
     hours = 0 
     minutes = int(raw[4]) 
    else: 
     hours, minutes = map(int,raw.split()[4].split(':')) 
    totalsecs = ((days * 24 + hours) * 60 + minutes) * 60 
    return totalsecs 

def uptime2(): 
    with open('/proc/uptime', 'r') as f: 
     uptime_seconds = float(f.readline().split()[0]) 
     return uptime_seconds 

当比较速度,第二种方法是围绕快50倍。尽管如此,直接调用系统调用应该是另一个更好的数量级。

>> import timeit 
>> print(timeit.timeit('ut.uptime1()', setup="import uptimecalls as ut", number=1000)) 
1.7286969429987948 
>> print(timeit.timeit('ut.uptime2()', setup="import uptimecalls as ut", number=1000)) 
0.03355383600865025 
+1

文件'/ proc中/'不是文件......他们最终都迷上了一些其他的东西让你设置/获取不同的东西。如果你愿意,你可以在python中加载'.so'文件。但不是0.03s/1000倍足够快? – HuStmpHrrr

回答

4

我不认为你可以得到比使用​​快得多打电话给sysinfo()但在我的测试中,它比/ proc慢。那些linux系统程序员似乎知道他们在做什么!

import ctypes 
import struct 

def uptime3(): 
    libc = ctypes.CDLL('libc.so.6') 
    buf = ctypes.create_string_buffer(4096) # generous buffer to hold 
              # struct sysinfo 
    if libc.sysinfo(buf) != 0: 
     print('failed') 
     return -1 

    uptime = struct.unpack_from('@l', buf.raw)[0] 
    return uptime 

运行你的两个测试以及矿上我的慢的笔记本电脑,我得到:

>>> print(timeit.timeit('ut.uptime1()', setup="import uptimecalls as ut", number=1000)) 
5.284219555993332 
>>> print(timeit.timeit('ut.uptime2()', setup="import uptimecalls as ut", number=1000)) 
0.1044210599939106 
>>> print(timeit.timeit('ut.uptime3()', setup="import uptimecalls as ut", number=1000)) 
0.11733305400412064 

UPDATE

大部分的时间都花在libc拉动和创建缓冲区。如果您打算长时间重复拨打电话,则可以将这些步骤从功能中拉出来,然后只测量系统呼叫。在这种情况下,该解决方案是明显的赢家:

uptime1: 5.066633300986723 
uptime2: 0.11561189399799332 
uptime3: 0.007740753993857652 
+0

确实他们会......谢谢。然而,第二个想法是,我相信这可以通过从函数调用中取出第一行或第二行来优化。 – kfx

+1

这是我与库和缓冲器为全局变量:uptime1:1.8627383150014794 uptime2:0.03709090399206616 uptime3:0.0018650189886102453 – kfx

+0

但基本上你展示了如何从Python中调用C库函数回答我的问题。 – kfx

4

你可以尝试安装psutil

pip install psutil 

,然后用下面的代码片段:

import psutil 
import time 


def seconds_elapsed(): 
    return time.time() - psutil.BOOT_TIME 


print seconds_elapsed() 
+1

我会感到非常惊讶,这可能是显著快于方法2:https://github.com/giampaolo/psutil/blob/master/psutil/_pslinux.py#L1255 – HuStmpHrrr

+1

我太多,但也许这是最快的跨平台和便携式解决方案,即使OP要求为linux – JuniorCompressor

+0

这个答案很无聊。这太简单了! ...(开玩笑)我想说:谢谢你这个很好的答案。 – guettli