transcurrido - Cómo recuperar el tiempo de inicio del proceso(o el tiempo de actividad) en Python
funciones de pandas para leer datos a tablas (6)
¿Cómo recuperar el tiempo de inicio del proceso (o el tiempo de actividad) en Python en Linux?
Solo sé, puedo llamar "ps -p my_process_id -f" y luego analizar la salida. Pero no está bien.
Aquí está el código basado en la respuesta de 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
Aunque no estoy seguro de si está bien. Escribí un programa de prueba que llama a sleep (5) y luego lo ejecuta y la salida es incorrecta y varía durante un par de segundos de una ejecución a otra. Esto está en una estación de trabajo vmware vm:
if __name__ == ''__main__'':
from time import sleep
sleep(5)
print proc_age_secs()
La salida es:
$ time python test.py
6.19169998169
real 0m5.063s
user 0m0.020s
sys 0m0.036s
Mediante el uso de 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''
>>>
... y además es multiplataforma, no solo Linux.
NB: Soy uno de los autores de este proyecto.
Si lo está haciendo desde el programa python que está tratando de medir, podría hacer algo como esto:
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
De lo contrario, no tiene más remedio que analizar ps
o entrar en /proc/pid
. Una buena forma de obtener el tiempo transcurrido es:
ps -eo pid,etime | grep $YOUR_PID | awk ''{print $2}''
Esto solo imprimirá el tiempo transcurrido en el siguiente formato, por lo que debería ser bastante fácil de analizar:
days-HH:MM:SS
(Si ha estado funcionando por menos de un día, es solo HH:MM:SS
)
La hora de inicio está disponible así:
ps -eo pid,stime | grep $YOUR_PID | awk ''{print $2}''
Desafortunadamente, si su proceso no comenzó hoy , solo le dará la fecha en que comenzó, en lugar de la hora.
La mejor manera de hacer esto es obtener el tiempo transcurrido y el tiempo actual y solo hacer un poco de matemáticas. La siguiente es una secuencia de comandos de python que toma un PID como argumento y hace lo anterior por usted, imprimiendo la fecha y hora de inicio del proceso:
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")
puedes analizar /proc/uptime
>>> uptime, idletime = [float(f) for f in open("/proc/uptime").read().split()]
>>> print uptime
29708.1
>>> print idletime
26484.45
Para las máquinas de Windows, probablemente puedas usar 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
man proc
dice que el elemento 22 en /proc/my_process_id/stat
es:
starttime %lu
El tiempo en jiffies el proceso comenzó después del inicio del sistema.
Su problema ahora es cómo determinar la longitud de un jiffy y cómo determinar cuándo arranca el sistema.
La respuesta para este último viene de man proc
: está en /proc/stat
, en una línea propia como esta:
btime 1270710844
Esa es una medida en segundos desde la época.
La respuesta para el primero no estoy seguro. man 7 time
dice:
El reloj del software, HZ y Jiffies
La precisión de muchas llamadas al sistema y las marcas de tiempo está limitada por la resolución del reloj del software, un reloj mantenido por el kernel que mide el tiempo en jiffies. El tamaño de un jiffy está determinado por el valor de la constante de núcleo
HZ
. El valor deHZ
varía según las versiones del kernel y las plataformas de hardware. En x86, la situación es la siguiente: en núcleos de hasta 2.4.x,HZ
fue de 100, lo que da un valor jiffy de 0.01 segundos; a partir de 2.6.0,HZ
se elevó a 1000, dando un tiempo de 0.001 segundos; desde el kernel 2.6.13, el valorHZ
es un parámetro de configuración del kernel y puede ser 100, 250 (el valor predeterminado) o 1000, lo que arroja un valor jiffies de, respectivamente, 0.01, 0.004 o 0.001 segundos.
Necesitamos encontrar HZ
, pero no tengo idea de cómo lo haría Python, excepto por la esperanza de que el valor sea 250 (ya que las afirmaciones de Wikipedia son las predeterminadas).
ps
obtiene así:
/* 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
Esto suena como un trabajo bien hecho por un módulo C muy pequeño para Python :)
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)