linux 如何在Python中检索进程开始时间(或正常运行时间)

wsxa1bj1  于 2023-08-03  发布在  Linux
关注(0)|答案(7)|浏览(112)

如何在Linux中检索python中的进程开始时间(或正常运行时间)?
我只知道,我可以调用“ps -p my_process_id -f”,然后解析输出。但这并不酷。

chy5wohz

chy5wohz1#

使用psutil https://github.com/giampaolo/psutil

>>> import psutil, os, time
>>> p = psutil.Process(os.getpid())
>>> p.create_time()
1293678383.0799999
>>> time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(p.create_time()))
'2010-12-30 04:06:23'
>>>

字符串
它是跨平台的,不仅仅是Linux。
NB:我是这个项目的作者之一。

irtuqstp

irtuqstp2#

如果你是在你要测量的Python程序中进行的,你可以这样做:

import time
# at the beginning of the script
startTime = time.time()
# ...
def getUptime():
    """
    Returns the number of seconds since the program started.
    """
    # do return startTime if you just want the process start time
    return time.time() - startTime

字符串
否则,您别无选择,只能解析ps或进入/proc/pid。一个很好的bash y获取运行时间的方法是:

ps -eo pid,etime | grep $YOUR_PID | awk '{print $2}'


这只会以下面的格式打印经过的时间,所以它应该很容易解析:

days-HH:MM:SS


(if它已经运行了不到一天,它只是HH:MM:SS
开始时间如下所示:

ps -eo pid,stime | grep $YOUR_PID | awk '{print $2}'


不幸的是,如果您的进程不是从 * 今天 * 开始的,则这将只给予它开始的日期,而不是时间。
最好的方法是获取经过的时间和当前时间,然后做一些数学运算。下面是一个python脚本,它将PID作为参数,并为您执行上述操作,打印出进程的开始日期和时间:

import sys
import datetime
import time
import subprocess

# call like this: python startTime.py $PID

pid = sys.argv[1]
proc = subprocess.Popen(['ps','-eo','pid,etime'], stdout=subprocess.PIPE)
# get data from stdout
proc.wait()
results = proc.stdout.readlines()
# parse data (should only be one)
for result in results:
    try:
        result.strip()
        if result.split()[0] == pid:
            pidInfo = result.split()[1]
            # stop after the first one we find
            break
    except IndexError:
        pass # ignore it
else:
    # didn't find one
    print "Process PID", pid, "doesn't seem to exist!"
    sys.exit(0)
pidInfo = [result.split()[1] for result in results
           if result.split()[0] == pid][0]
pidInfo = pidInfo.partition("-")
if pidInfo[1] == '-':
    # there is a day
    days = int(pidInfo[0])
    rest = pidInfo[2].split(":")
    hours = int(rest[0])
    minutes = int(rest[1])
    seconds = int(rest[2])
else:
    days = 0
    rest = pidInfo[0].split(":")
    if len(rest) == 3:
        hours = int(rest[0])
        minutes = int(rest[1])
        seconds = int(rest[2])
    elif len(rest) == 2:
        hours = 0
        minutes = int(rest[0])
        seconds = int(rest[1])
    else:
        hours = 0
        minutes = 0
        seconds = int(rest[0])

# get the start time
secondsSinceStart = days*24*3600 + hours*3600 + minutes*60 + seconds
# unix time (in seconds) of start
startTime = time.time() - secondsSinceStart
# final result
print "Process started on",
print datetime.datetime.fromtimestamp(startTime).strftime("%a %b %d at %I:%M:%S %p")

yfjy0ee7

yfjy0ee73#

man proc表示/proc/my_process_id/stat中的第22项是:
starttime %lu
系统 Boot 后进程启动的时间,以jiffies为单位。
现在的问题是,如何确定jiffy的长度以及如何确定系统何时启动。
后者的答案仍然来自man proc:它在/proc/stat中,在它自己的一行上,如下所示:

btime 1270710844

字符串
这是自纪元以来的秒测量值。
前者的答案我不确定。man 7 time说:

软件时钟、HZ和Jiffies

许多系统调用和时间戳的准确性受到软件时钟分辨率的限制,软件时钟是由内核维护的时钟,以jiffies为单位测量时间。jiffy的大小由内核常量HZ的值决定。HZ的值因内核版本和硬件平台而异。在x86上,情况如下:在直到并包括2.4.x的内核上,HZ为100,给出0.01秒的瞬时值;从2.6.0开始,HZ上升到1000,给出0.001秒的瞬间;从内核2.6.13开始,HZ值是内核配置参数,可以是100、250(默认值)或1000,分别产生0.01、0.004或0.001秒的jiffies值。
我们需要找到HZ,但我不知道如何从Python中找到它,除了希望值是250(维基百科声称是默认值)。
ps这样得到:

/* sysinfo.c init_libproc() */
  if(linux_version_code > LINUX_VERSION(2, 4, 0)){ 
    Hertz = find_elf_note(AT_CLKTCK);
    //error handling
  }
  old_Hertz_hack(); //ugh


这听起来像是一个非常小的Python C模块所做的工作:)

xdyibdwo

xdyibdwo4#

下面是基于badp答案的代码:

import os
from time import time

HZ = os.sysconf(os.sysconf_names['SC_CLK_TCK'])

def proc_age_secs():
    system_stats = open('/proc/stat').readlines()
    process_stats = open('/proc/self/stat').read().split()
    for line in system_stats:
        if line.startswith('btime'):
            boot_timestamp = int(line.split()[1])
    age_from_boot_jiffies = int(process_stats[21])
    age_from_boot_timestamp = age_from_boot_jiffies / HZ
    age_timestamp = boot_timestamp + age_from_boot_timestamp
    return time() - age_timestamp

字符串
但我不确定这样对不对。我写了一个测试程序,它调用sleep(5),然后运行它,输出是错误的,并且在几秒钟内从运行到运行都有变化。这是在一个vmware工作站虚拟机:

if __name__ == '__main__':
    from time import sleep
    sleep(5)
    print proc_age_secs()


输出为:

$ time python test.py
6.19169998169

real    0m5.063s
user    0m0.020s
sys     0m0.036s

1tu0hz3e

1tu0hz3e5#

def proc_starttime(pid=os.getpid()):
    # https://gist.github.com/westhood/1073585
    p = re.compile(r"^btime (\d+)$", re.MULTILINE)
    with open("/proc/stat") as f:
        m = p.search(f.read())
    btime = int(m.groups()[0])

    clk_tck = os.sysconf(os.sysconf_names["SC_CLK_TCK"])
    with open("/proc/%d/stat" % pid) as f:
        stime = int(f.read().split()[21]) / clk_tck

    return datetime.fromtimestamp(btime + stime)

字符串

g52tjvyc

g52tjvyc6#

你可以解析/proc/uptime

>>> uptime, idletime = [float(f) for f in open("/proc/uptime").read().split()]
>>> print uptime
29708.1
>>> print idletime
26484.45

字符串
对于windows机器,您可能可以使用wmi

import wmi
c = wmi.WMI()
secs_up = int([uptime.SystemUpTime for uptime in c.Win32_PerfFormattedData_PerfOS_System()][0])
hours_up = secs_up / 3600
print hours_up

cwdobuhd

cwdobuhd7#

此实现基于Dan Benamy's answer,并通过使用以秒为单位的正常运行时间而不是自纪元以来以秒为单位的 Boot 时间来简化。该方法在Python 2和Python 3上进行了测试。

import os
import time

def processRealTimeSeconds():
    uptimeSeconds = float(open("/proc/uptime").readline().split()[0])
    procStartJif = float(open("/proc/self/stat").readline().split()[21])

    clockTicks = os.sysconf(os.sysconf_names["SC_CLK_TCK"])
    procStartSecondsBoot = procStartJif / clockTicks

    return uptimeSeconds - procStartSecondsBoot

if __name__ == '__main__':
    time.sleep(5)
    print("Real process time: {} s".format(processRealTimeSeconds()))

字符串
输出量:

$ time ./processTime.py 
Real process time: 5.060000000012224 s

real    0m5.059s
user    0m0.041s
sys     0m0.013s

相关问题